📄 bugfix80.txt
字号:
** This is our Bug Fix list for Patches to **
** PC-lint / FlexeLint Version 8.00 **
*************** Version 8.00o 1/16/2004 ***************
* We were issuing an undeserved Error 304 Corrupt object file, code 4
when processing the lob file resulting from an unsuccessful attempt
to pass an object to a function template having a parameter of the
form A<T> where T is a parameter of the function template.
* Preprocessor variable __STDC_VERSION__ was being defined even though
the option -A(C90) was given. This fix was scheduled to go into 8.00n
but didn't quite make it.
* For gcc (option -cgnu) we have a special mode in which std::name
(where name is any identifier) refers either to a name within
namespace std or a name in the global namespace. Instead of
looking solely in the global namespace we were looking in all
namespaces (unqualified name lookup) which opened the door to
finding the wrong name.
* We no longer issue warnings for objects of a class type when the class
has no data members.
* We added an additional parameter to message 1502 to designate the
class so that the message may be suppressed by the class as well as
by the object
* We were complaining that an array (of classes) member was not
initialized by a constructor when the array would have been
initialized by the default constructor.
* We were issuing an undeserved 1527 (static member not defined)
for a constant static member that has a constant initializer.
* We were issuing an undeserved 1540 (pointer member neither freed
nor zero'ed by destructor) for a volatile pointer that is clearly
zero'ed.
* We were experiencing an infinite loop in the following code:
template< typename T > struct F
{
template <class U> static bool g( void(U::*)(void) );
template <class U> static int g( ... );
enum { h = g<T>(0) };
};
In general, the invocation of a member template function within an
enum had the effect of creating a data loop.
* The C99 keyword, restrict, is defined for all C programs (unless the
-A(C90) option, or equivalent, is given).
* We were not supporting member function template specializations
defined outside of the class that were not declared inside the class.
For example:
class C
{
template<typename T> void f(T) { }
// template<> void f( int );
};
template<> void C::f( int ) { }
was not previously accepted without the declaration shown commented out.
This construction is specifically permitted by the C++ standard.
* We would sometimes give an undeserved complaint to the effect
that a member of an anonymous union was uninitialized.
* We were issuing an undeserved Misra Rule 54 violation (null statement
is not on a line by itself) when processing a null statement in an
inline class member function.
* We were issuing an undeserved 1918 (empty prototype for member
declaration) for generated default constructors.
* We were issuing an undeserved Warning 1540 (pointer member not
freed in a destructor) for constant pointers.
* We've added the inline keyword for C99.
* We were not accepting pointer to member as a bool and conversion
functions that return pointer to members are being ignored when a
class containing same is used as a bool.
* We were not promoting a protected member to public through a
private derivation. E.g.
class B{ protected: int b; };
class BB : private B { public: using B::b; }
void f() { BB bb; bb.b = 3; }
drew an undeserved complaint since this makes b a public member of BB.
* We were issuing a confusing message after reporting an unreachable
semi-colon. E.g.
int f()
{ if( ... ) return 0; exit(1);; }
would report that f() is not returning anything. We still report that
the semi-colon is unreachable, but we assume what follows is also
unreachable. (The double semi-colon was more likely to arise in
connection with macros)
* Our Misra Rule 47 check that guards against a reliance on
C's operator precedence has been revised and improved.
* The use of A::A rather than A to identify a constructor for
A was giving us problems in expression contexts. For example:
struct A { };
A a = A::A();
would give an unjustified Error 1032.
* We were giving an undeserved warning (541, excessive character size)
in wide-character literal strings where an escaped sequence
produced a value that was too wide for a normal byte but was not
wider than a wide character.
* We were not reporting (under Unix and Linux which by default uses
split options) that there is something amiss with the following
/*lint -e */
* Parentheses are now allowed in split options. Thus
"-elib(345)" when written as a split option previously had to be
written as "-elib 345". Now it can also be written as "-elib (345)"
* The -vo verbosity option was not accurately reflecting the value
of split options.
* When parsing a base class specifier we were supposed to ignore
names that are not class names. E.g. we were giving error
message 1016 for:
enum A { C };
class C{};
class D : public C { }; // 1016
We now correctly pick out class C rather than enumerator C.
* The -emacro option was creating a problem when it names a macro
that is used directly after a '/' in the source code. For
example:
//lint -emacro(506,R)
#define R 10
int n = 100/R;
* Under certain circumstances the expression within an if clause
could be mischaracterized as a declaration. E.g. the following
works as expected:
struct Q { Q(); };
struct L { L(); Q operator[]( unsigned i ) const; };
struct U { U( Q ); bool f(); };
L a;
...
if( U( a[30] ).f() ) ...
* We were not issuing a Misra Rule 63 violation for a C program
containing a switch statement whose switch expression is a Boolean.
E.g.
switch( a < b ) /* should produce message 961, rule 63 */
* We were not allowing friend functions defined in-line special
lookup privileges as in:
struct T { enum E { r }; friend void f() { E e = r; } };
Here the E and r should be visible to the function f() since
it is defined within the class T.
* We were giving an undeserved initializer inversion Informational (1729)
when a member typedef was used to specify a base class. E.g.
class C : public B {
int a; typedef B X;
C() : X(), a(0) { ...
* We were giving an undeserved 1063 (copy constructor parameter should
be a reference) when the parameter is the ellipsis. E.g.,
class A { A(...); };
* Our macro processing was not adhering to the standard in a
way that would show up in a macroized #include statement.
As an example:
#define Sep() /
#define Dir() xxx
#define Name() y.h
#define Header <Dir()Sep()Name()>
#include Dir()Sep()Name()
would induce us to open <xxxSep()y.h> because the result of Dir()
would be tacked onto "Sep()" yielding a name xxxSep with no macro
association. The standard requires that the identifiers be
kept separate so that now we would attempt to open <xxx/y.h>
There may be some folks (or programs) out there still using an
ancient concatenation method exemplified as follows:
#define Prefix() x
int Prefix()y;
This will no longer work by default as it is non-compliant. To
get it to work you will need the option +fmc (macro concatenation).
This is described in readme.txt.
* We no longer issue Elective Notes 1917 and 1918 (vacuous argument
list) for destructors as these never have arguments anyway.
* We had a problem with Universal Naming Convention (UNC) pathnames.
A file such as "//x.c" might have a "C:" (or whatever the
current drive letter) prepended to it. This would normally affect
only presentation purposes. It could also affect subsequent header
searching if the misnamed file then includes other headers and if
the +fdi (Directory of Including file) flag was set.
* ANSI translation limits have been upgraded to reflect those of
C99. To obtain the older limits use -A(C90).
* An extra blank could appear in the expansion of a macro sequence.
For example:
#define f(a)
#define t(a) a
#define g f
#define h g
#define i h
t(i)b
previously would result in "f b". It now properly results in "fb"
* An extra blank could appear in the expansion of a function like
macro if the name of the macro is separated from the '('. E.g.
#define A(b) b
#define B A (<c.h>)
#include B
Attempted to open " c.h" instead of "c.h"
* An unparenthesized '<' within a default value for a template
parameter was throwing off our attempt to find a balancing '>'
in the following example:
template< class T, bool b = T(-1) < T(0) > struct A;
*************** Version 8.00n 10/16/2003 ***************
* We were not supporting anonymous unions under C at the global
level but only within struct's. Though non-standard, anonymous
unions are supported by the IAR compiler and even appear within
IAR headers. Under C you will need the +fan option to activate
anonymous unions.
* We were not catching a fairly obvious null pointer usage:
struct S { char a[10]; };
void f() { S *p = 0; p->a[0] = 0; ... }
* The _Bool keyword is now built-in as per the C99 spec.
* We were issuing an undeserved Error 64 when passing a reference
to a constructorless class. E.g.
struct X { int a; }; void f( X ); void g( X & y ) { f( y ); }
* An option to modify the library flag was ineffective just after
a function template definition. The sequence:
template <...> type f(...){...} /*lint --flb */
read the option before processing the definition resulting in
no change to the library flag.
* We were issuing an undeserved header-not-used message (766)
when the header would contain a template definition and the
template was accessed through a typedef.
* We were issuing template instantiation errors at wrap-up time for
modules that did not declare the templates.
* We were giving a false complaint about ignoring the return value
of operator new even though it was clearly not being ignored.
This could have occurred when the type being new'ed required
instantiation.
* We were not treating a member function within a class within a
member function properly. Unqualified name lookup could find the
wrong name.
* We were issuing internal error 265 and stopping when the file
consisted only of
C::C : a(0) { }
We now move on to the next declaration after issuing appropriate
error messages.
* We were not evaluating expressions involving strong Booleans properly
if the strong Booleans were enum's. Thus:
/*lint -strong(AJXB, B) */ enum E; typedef enum E B;
#if ! ( 0 && 0 )
...
The if would be evaluated incorrectly as 0 rather than 1.
* Under some circumstances when only a subset of a set of overloaded
functions were redeclared for a new module leaving some undeclared
there was the possibility of having some confusion between a more
appropriate function not declared and a less appropriate function
that was declared.
* An inference that if( p - q ) were true where p and q were pointers
might infer something improper about p or q.
* The use of the +fct (Create Tag) flag could result in unjustified
tag errors as some of the created tags could inadvertently conflict.
* Preprocessor variable __STDC_VERSION__ was being defined even though
the option -A(C90) was given.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -