This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Updated GCC vs Clang diagnostics [Was: Switching to C++ by default in 4.8]


Thanks for preparing the wiki page. I have looked at the examples from
this slide: http://ecn.channel9.msdn.com/events/GoingNative12/GN12Clang.pdf
with trunk gcc. In some cases, gcc's warning matches that of clang but
in majority of cases, gcc either emits no warnings or worse ones. The
warnings in the comments are from clang.  One possible advantage of
clang is that adding new warnings is relatively easier.

Another side note. This slide mentioned two things: 1) thread-safety
static check; 2) compiler based dynamic check. The first one was first
introduced in a gcc branch but never made into the mainline, but now
it is getting into Clang. 2) Gcc work on dynamic check was also done
partially,  but not made into trunk either.

Gcc command line option: -fsyntax-only -Wall -std=c++11


thanks,

David



Example 1:  Gcc produces nothing even with -Warray-bounds
--------------------------------------------------------------------------------
int foo() {
   int arr[100];
   // ...
  return arr[100];
 }

 /*

 array.cpp:4:10: warning: array index 100 is past the end of the array
(which contains 100 elements) [-Warray-bounds]
  return arr[100];
         ^   ~~~
array.cpp:2:3: note: array 'arr' declared here
  int arr[100];
  ^
1 warning generated.

*/

Example 2: gcc produces nothing even with -Warray-bounds
--------------------------------------------------------------------------------
  constexpr int arr_size = 42;
  constexpr int N = 44;
  void f(int);
  int test() {
    int arr[arr_size];
   // ...
    f(arr[N]);
    // ...
   if (N < arr_size) return arr[N];
   return 0;
 }

/*

deadcode.cpp:7:5: warning: array index 44 is past the end of the array
(which contains 42 elements) [-Warray-bounds]
  f(arr[N]);
    ^   ~
deadcode.cpp:5:3: note: array 'arr' declared here
  int arr[arr_size];
  ^
1 warning generated.

*/

Example 3: nothing from gcc:
---------------------------------------

 #include <memory.h>
 struct S { int a, b, c; float vec[16]; };
 void test(S *s) {
   // ...
   memset(s, 0, sizeof(s));
   // ...
 }

 /*

memset.cpp:5:23: warning: argument to 'sizeof' in 'memset' call is the
same expression as the destination; did you mean to dereference it? [-
Wsizeof-pointer-memaccess]
  memset(s, 0, sizeof(s));
         ~            ^
1 warning generated.

*/

Example 4: Nothing from gcc:
----------------------------------------

static const long long
   DiskCacheSize = 8 << 30; // 8 Gigs

/*

overflow.cpp:1:42: warning: signed shift result (0x200000000) requires 35
bits to represent, but 'int' only has 32 bits [-Wshift-overflow]
static const long long DiskCacheSize = 8 << 30; // 8 Gigs
                                       ~ ^  ~~
1 warning generated.

*/


Example 5: More suggestions from clang --> suggesting changing = to ==
-------------------------------------------------------------------------------------------------

 void foo();
 void bar();
 void test(int i) {
   // ...
  if (i = 42) foo();
   else bar();
 }

 /*

 parentheses1.cpp:5:9: warning: using the result of an assignment as a
condition without parentheses [-Wparentheses]
  if (i = 42) foo();
      ~~^~~~
parentheses1.cpp:5:9: note: place parentheses around the assignment to
silence this warning
  if (i = 42) foo();
        ^
      (     )
parentheses1.cpp:5:9: note: use '==' to turn this assignment into an
equality comparison
  if (i = 42) foo();
        ^
        ==
1 warning generated.

*/


Example 6: Nothing from gcc
-------------------------------------------
 int get();
 void test() {
   int i = get();
  // ...
  if ((i == get())) {
     // ...
   }
 }

 /*
 parentheses2.cpp:5:10: warning: equality comparison with extraneous
parentheses [-Wparentheses-equality]
  if ((i == get())) {
       ~~^~~~~~~~
parentheses2.cpp:5:10: note: remove extraneous parentheses around the
comparison to silence this warning
  if ((i == get())) {
      ~  ^       ~
parentheses2.cpp:5:10: note: use '=' to turn this equality comparison
into an assignment
  if ((i == get())) {
         ^~
         =
1 warning generated.

*/

Example 7: Nothing from gcc
----------------------------------------

 int test(bool b, int x, int y) {
   return 42 + b ? x : y;
 }

/*

parentheses4.cpp:2:17: warning: operator '?:' has lower precedence than
'+'; '+' will be evaluated first [-Wparentheses]
  return 42 + b ? x : y;
         ~~~~~~ ^
parentheses4.cpp:2:17: note: place parentheses around the '+' expression
to silence this warning
  return 42 + b ? x : y;
                ^
         (     )
parentheses4.cpp:2:17: note: place parentheses around the '?:' expression
to evaluate it first
  return 42 + b ? x : y;
                ^
              (        )
1 warning generated.

*/

Example 8: No useful suggestions for corrections from gcc:
-----------------------------------------------------------------------------
struct BaseType {};
struct DerivedType : public BaseType {
  static int base_type;
  DerivedType() : basetype() {}
};


/*

typo1.cpp:4:19: error: initializer 'basetype' does not name a non-static
data member or base class; did you mean the base class 'BaseType'?
  DerivedType() : basetype() {}
                  ^~~~~~~~
                  BaseType
typo1.cpp:2:22: note: base class 'BaseType' specified here
struct DerivedType : public BaseType {
                     ^~~~~~~~~~~~~~~
1 error generated.

*/

Example 9:  Same as example 8:
---------------------------------------------

namespace fiz { namespace bang {
   int foobar();
 } }
 int test() {
   return bang::Foobar();
 }

/*

typo2.cpp:5:10: error: use of undeclared identifier 'bang'; did you mean
'fiz::bang'?
  return bang::Foobar();
         ^~~~
         fiz::bang
typo2.cpp:1:27: note: 'fiz::bang' declared here
namespace fiz { namespace bang {
                          ^
typo2.cpp:5:16: error: no member named 'Foobar' in namespace 'fiz::bang';
did you mean 'foobar'?
  return bang::Foobar();
         ~~~~~~^~~~~~
               foobar
typo2.cpp:2:7: note: 'foobar' declared here
  int foobar();
      ^
2 errors generated.

*/

Example 10: nothing from gcc:
------------------------------------------

 struct S { int n; };
 S bar();
 S test() {
   S foo,
   bar();
   // ...
  return foo;
 }

/*

conversions.cppreturn.cpvexing.cpp
vexing.cpp:5:6: warning: empty parentheses interpreted as a function
declaration [-Wvexing-parse]
  bar();
     ^~
vexing.cpp:4:8: note: change this ',' to a ';' to call 'bar'
  S foo,
       ^
       ;
vexing.cpp:5:6: note: replace parentheses with an initializer to declare
a variable
  bar();
     ^~
     {}
1 warning generated.

*/

Example 11: nothing from gcc:
-----------------------------------------

 int test(int i) {
   if (i > 42);
     return 42;
   return i;
 }

 /*

 emptyif.cpp:2:14: warning: if statement has empty body [-Wempty-body]
  if (i > 42);
             ^
1 warning generated.

*/

Example  12:  Worse source information for MACRO in gcc:
-----------------------------------------------------------------------------

#define M1(x, y, z) y();
#define M2(x, y, z) M1(x, y, z)
void test() {
   M2(a, b, c);
}

/* ===== Clang

macros1.cpp:4:9: error: use of undeclared identifier 'b'
  M2(a, b, c);
        ^
macros1.cpp:2:27: note: expanded from macro 'M2'
#define M2(x, y, z) M1(x, y, z)
                          ^
macros1.cpp:1:21: note: expanded from macro 'M1'
#define M1(x, y, z) y();
                    ^
1 error generated.

================ */

Example 13: nothing from gcc:
---------------------------------------

template <class T, class U> struct S {};
  template <typename... Ts> void f(Ts...);

  template <typename... Ts> struct X {
    template <typename... Us> void g() {
      f(S<Ts, Us>()...);
    }
  };

 void test(X<int, float> x) {
   x.g<int, float, double>();
 }


/*

oscar-wilde.cpp:6:18: error: pack expansion contains parameter packs 'Ts'
and 'Us' that have different lengths (2 vs. 3)
    f(S<Ts, Us>()...);
        ~~  ~~   ^
oscar-wilde.cpp:11:5: note: in instantiation of function template
specialization 'X<int, float>::g<int, float, double>' requested here
  x.g<int, float, double>();
    ^
1 error generated.

*/

Example 14: Nothing from gcc:

template <int N> struct S1 { int arr[N - 5]; };
template <typename T> struct S2 { S1<sizeof(T)> s1; };
template <typename T> void foo(T x) { S2<T> s2; }
void test() { foo(42); }

/* From Clang:
templates1.cpp:1:38: error: 'arr' declared as an array with a negative
size
template <int N> struct S1 { int arr[N - 5]; };
                                     ^~~~~
templates1.cpp:2:49: note: in instantiation of template class 'S1<4>'
requested here
template <typename T> struct S2 { S1<sizeof(T)> s1; };
                                                ^
templates1.cpp:3:45: note: in instantiation of template class 'S2<int>'
requested here
template <typename T> void foo(T x) { S2<T> s2; }
                                            ^
templates1.cpp:4:15: note: in instantiation of function template
specialization 'foo<int>' requested here
void test() { foo(42); }
==============================================     */







On Thu, Apr 12, 2012 at 12:43 PM, Jonathan Wakely <jwakely.gcc@gmail.com> wrote:
> On 12 April 2012 11:41, Jonathan Wakely wrote:
>> Two more examples, then I'll save it for a wiki page instead of the
>> mailing list:
>
> And here it is:
>
> http://gcc.gnu.org/wiki/ClangDiagnosticsComparison


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]