mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-30 17:21:10 +00:00
Add notes for suppressing and (if it's a zero-arg function returning bool) fixing the function-to-bool conversion warning.
llvm-svn: 146280
This commit is contained in:
parent
66af99eb34
commit
10eb4b67d8
@ -2692,6 +2692,7 @@ public:
|
||||
explicit BinaryOperator(EmptyShell Empty)
|
||||
: Expr(BinaryOperatorClass, Empty), Opc(BO_Comma) { }
|
||||
|
||||
SourceLocation getExprLoc() const { return OpLoc; }
|
||||
SourceLocation getOperatorLoc() const { return OpLoc; }
|
||||
void setOperatorLoc(SourceLocation L) { OpLoc = L; }
|
||||
|
||||
|
@ -1657,6 +1657,10 @@ def warn_impcast_null_pointer_to_integer : Warning<
|
||||
def warn_impcast_function_to_bool : Warning<
|
||||
"address of function %q0 will always evaluate to 'true'">,
|
||||
InGroup<BoolConversions>;
|
||||
def note_function_to_bool_silence : Note<
|
||||
"prefix with the address-of operator to silence this warning">;
|
||||
def note_function_to_bool_call : Note<
|
||||
"suffix with parentheses to turn this into a function call">;
|
||||
|
||||
def warn_cast_align : Warning<
|
||||
"cast from %0 to %1 increases required alignment from %2 to %3">,
|
||||
|
@ -3771,6 +3771,16 @@ void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
|
||||
if (FunctionDecl* F = dyn_cast<FunctionDecl>(D)) {
|
||||
S.Diag(E->getExprLoc(), diag::warn_impcast_function_to_bool)
|
||||
<< F << E->getSourceRange() << SourceRange(CC);
|
||||
S.Diag(E->getExprLoc(), diag::note_function_to_bool_silence)
|
||||
<< FixItHint::CreateInsertion(E->getExprLoc(), "&");
|
||||
QualType ReturnType;
|
||||
UnresolvedSet<4> NonTemplateOverloads;
|
||||
S.isExprCallable(*E, ReturnType, NonTemplateOverloads);
|
||||
if (!ReturnType.isNull()
|
||||
&& ReturnType->isSpecificBuiltinType(BuiltinType::Bool))
|
||||
S.Diag(E->getExprLoc(), diag::note_function_to_bool_call)
|
||||
<< FixItHint::CreateInsertion(
|
||||
S.getPreprocessor().getLocForEndOfToken(E->getLocEnd()), "()");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
||||
// RUN: %clang_cc1 -fsyntax-only -verify -Wno-bool-conversions %s
|
||||
|
||||
typedef __typeof__(((int*)0)-((int*)0)) ptrdiff_t;
|
||||
|
||||
@ -100,8 +100,8 @@ int main()
|
||||
{ (void) reinterpret_cast<int>(two); } //expected-error {{reinterpret_cast}}
|
||||
{ (void) reinterpret_cast<int (*)(char, double)>(two); } //expected-error {{reinterpret_cast}}
|
||||
|
||||
{ bool b = (twoT<int>); } // expected-warning {{address of function 'twoT<int>' will always evaluate to 'true'}}
|
||||
{ bool b = (twoT<int, int>); } // expected-warning {{address of function 'twoT<int, int>' will always evaluate to 'true'}}
|
||||
{ bool b = (twoT<int>); }
|
||||
{ bool b = (twoT<int, int>); }
|
||||
|
||||
{ bool b = &twoT<int>; //&foo<int>; }
|
||||
b = &(twoT<int>); }
|
||||
@ -142,20 +142,20 @@ namespace member_pointers {
|
||||
if (&s.f<char>) return; // expected-error {{cannot create a non-constant pointer to member function}}
|
||||
if (&s.f<int>) return; // expected-error {{cannot create a non-constant pointer to member function}}
|
||||
|
||||
if (S::g<char>) return; // expected-warning {{address of function 'member_pointers::S::g<char>' will always evaluate to 'true'}}
|
||||
if (S::g<int>) return; // expected-warning {{address of function 'member_pointers::S::g<int>' will always evaluate to 'true'}}
|
||||
if (S::g<char>) return;
|
||||
if (S::g<int>) return;
|
||||
if (&S::g<char>) return;
|
||||
if (&S::g<int>) return;
|
||||
if (s.g<char>) return; // expected-warning {{address of function 'member_pointers::S::g<char>' will always evaluate to 'true'}}
|
||||
if (s.g<int>) return; // expected-warning {{address of function 'member_pointers::S::g<int>' will always evaluate to 'true'}}
|
||||
if (s.g<char>) return;
|
||||
if (s.g<int>) return;
|
||||
if (&s.g<char>) return;
|
||||
if (&s.g<int>) return;
|
||||
|
||||
if (S::h<42>) return; // expected-warning {{address of function 'member_pointers::S::h<42>' will always evaluate to 'true'}}
|
||||
if (S::h<42>) return;
|
||||
if (S::h<int>) return; // expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}}
|
||||
if (&S::h<42>) return;
|
||||
if (&S::h<int>) return;
|
||||
if (s.h<42>) return; // expected-warning {{address of function 'member_pointers::S::h<42>' will always evaluate to 'true'}}
|
||||
if (s.h<42>) return;
|
||||
if (s.h<int>) return; // expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}}
|
||||
if (&s.h<42>) return;
|
||||
if (&s.h<int>) return; // expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}}
|
||||
@ -170,20 +170,20 @@ namespace member_pointers {
|
||||
{ bool b = &s.f<char>; } // expected-error {{cannot create a non-constant pointer to member function}}
|
||||
{ bool b = &s.f<int>; } // expected-error {{cannot create a non-constant pointer to member function}}
|
||||
|
||||
{ bool b = S::g<char>; } // expected-warning {{address of function 'member_pointers::S::g<char>' will always evaluate to 'true'}}
|
||||
{ bool b = S::g<int>; } // expected-warning {{address of function 'member_pointers::S::g<int>' will always evaluate to 'true'}}
|
||||
{ bool b = S::g<char>; }
|
||||
{ bool b = S::g<int>; }
|
||||
{ bool b = &S::g<char>; }
|
||||
{ bool b = &S::g<int>; }
|
||||
{ bool b = s.g<char>; } // expected-warning {{address of function 'member_pointers::S::g<char>' will always evaluate to 'true'}}
|
||||
{ bool b = s.g<int>; } // expected-warning {{address of function 'member_pointers::S::g<int>' will always evaluate to 'true'}}
|
||||
{ bool b = s.g<char>; }
|
||||
{ bool b = s.g<int>; }
|
||||
{ bool b = &s.g<char>; }
|
||||
{ bool b = &s.g<int>; }
|
||||
|
||||
{ bool b = S::h<42>; } // expected-warning {{address of function 'member_pointers::S::h<42>' will always evaluate to 'true'}}
|
||||
{ bool b = S::h<42>; }
|
||||
{ bool b = S::h<int>; } // expected-error {{can't form member pointer of type 'bool' without '&' and class name}}
|
||||
{ bool b = &S::h<42>; }
|
||||
{ bool b = &S::h<int>; }
|
||||
{ bool b = s.h<42>; } // expected-warning {{address of function 'member_pointers::S::h<42>' will always evaluate to 'true'}}
|
||||
{ bool b = s.h<42>; }
|
||||
{ bool b = s.h<int>; } // expected-error {{can't form member pointer of type 'bool' without '&' and class name}}
|
||||
{ bool b = &s.h<42>; }
|
||||
{ bool b = &s.h<int>; } // expected-error {{can't form member pointer of type 'bool' without '&' and class name}}
|
||||
|
@ -49,7 +49,8 @@ void test3() {
|
||||
if ("help")
|
||||
(void) 0;
|
||||
|
||||
if (test3) // expected-warning {{address of function 'test3' will always evaluate to 'true'}}
|
||||
if (test3) // expected-warning {{address of function 'test3' will always evaluate to 'true'}} \
|
||||
expected-note {{prefix with the address-of operator to silence this warning}}
|
||||
(void) 0;
|
||||
}
|
||||
|
||||
|
@ -12,13 +12,25 @@ struct S2 {
|
||||
static void f4() __attribute__((weak_import));
|
||||
};
|
||||
|
||||
bool f5();
|
||||
bool f6(int);
|
||||
|
||||
void bar() {
|
||||
bool b;
|
||||
|
||||
b = f1; // expected-warning {{address of function 'f1' will always evaluate to 'true'}}
|
||||
if (f1) {} // expected-warning {{address of function 'f1' will always evaluate to 'true'}}
|
||||
b = S::f2; // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}}
|
||||
if (S::f2) {} // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}}
|
||||
b = f1; // expected-warning {{address of function 'f1' will always evaluate to 'true'}} \
|
||||
expected-note {{prefix with the address-of operator to silence this warning}}
|
||||
if (f1) {} // expected-warning {{address of function 'f1' will always evaluate to 'true'}} \
|
||||
expected-note {{prefix with the address-of operator to silence this warning}}
|
||||
b = S::f2; // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}} \
|
||||
expected-note {{prefix with the address-of operator to silence this warning}}
|
||||
if (S::f2) {} // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}} \
|
||||
expected-note {{prefix with the address-of operator to silence this warning}}
|
||||
b = f5; // expected-warning {{address of function 'f5' will always evaluate to 'true'}} \
|
||||
expected-note {{prefix with the address-of operator to silence this warning}} \
|
||||
expected-note {{suffix with parentheses to turn this into a function call}}
|
||||
b = f6; // expected-warning {{address of function 'f6' will always evaluate to 'true'}} \
|
||||
expected-note {{prefix with the address-of operator to silence this warning}}
|
||||
|
||||
// implicit casts of weakly imported symbols are ok:
|
||||
b = f3;
|
||||
|
@ -41,7 +41,7 @@ int main()
|
||||
*oneT<int>; // expected-warning {{expression result unused}}
|
||||
*two; //expected-error {{reference to overloaded function could not be resolved; did you mean to call it with no arguments?}} expected-error {{indirection requires pointer operand}}
|
||||
*twoT<int>; //expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}}
|
||||
!oneT<int>; // expected-warning {{expression result unused}} expected-warning {{address of function 'oneT<int>' will always evaluate to 'true'}}
|
||||
!oneT<int>; // expected-warning {{expression result unused}} expected-warning {{address of function 'oneT<int>' will always evaluate to 'true'}} expected-note {{prefix with the address-of operator to silence this warning}}
|
||||
+oneT<int>; // expected-warning {{expression result unused}}
|
||||
-oneT<int>; //expected-error {{invalid argument type}}
|
||||
oneT<int> == 0; // expected-warning {{equality comparison result unused}} \
|
||||
@ -53,7 +53,7 @@ int main()
|
||||
|
||||
int i = (int) (false ? (void (*)(int))twoT<int> : oneT<int>); //expected-error {{incompatible operand}}
|
||||
(twoT<int>) == oneT<int>; //expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}} {{cannot resolve overloaded function 'twoT' from context}}
|
||||
bool b = oneT<int>; // expected-warning {{address of function 'oneT<int>' will always evaluate to 'true'}}
|
||||
bool b = oneT<int>; // expected-warning {{address of function 'oneT<int>' will always evaluate to 'true'}} expected-note {{prefix with the address-of operator to silence this warning}}
|
||||
void (*p)() = oneT<int>;
|
||||
test<oneT<int> > ti;
|
||||
void (*u)(int) = oneT<int>;
|
||||
|
Loading…
Reference in New Issue
Block a user