forked from OSchip/llvm-project
Catch a few more cases of illegal comparisons.
llvm-svn: 79793
This commit is contained in:
parent
79ba8f2edc
commit
16c209610c
|
@ -1352,6 +1352,8 @@ def ext_typecheck_ordered_comparison_of_pointer_and_zero : Extension<
|
|||
"ordered comparison between pointer and zero (%0 and %1) is an extension">;
|
||||
def ext_typecheck_ordered_comparison_of_function_pointers : ExtWarn<
|
||||
"ordered comparison of function pointers (%0 and %1)">;
|
||||
def ext_typecheck_comparison_of_fptr_to_void : Extension<
|
||||
"equality comparison between function pointer and void pointer (%0 and %1)">;
|
||||
def ext_typecheck_comparison_of_pointer_integer : ExtWarn<
|
||||
"comparison between pointer and integer (%0 and %1)">;
|
||||
def ext_typecheck_comparison_of_distinct_pointers : ExtWarn<
|
||||
|
|
|
@ -4237,28 +4237,10 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
|
|||
QualType RCanPointeeTy =
|
||||
Context.getCanonicalType(rType->getAs<PointerType>()->getPointeeType());
|
||||
|
||||
if (isRelational) {
|
||||
if (lType->isFunctionPointerType() || rType->isFunctionPointerType()) {
|
||||
Diag(Loc, diag::ext_typecheck_ordered_comparison_of_function_pointers)
|
||||
<< lType << rType << lex->getSourceRange() << rex->getSourceRange();
|
||||
}
|
||||
if (LCanPointeeTy->isVoidType() != RCanPointeeTy->isVoidType()) {
|
||||
Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers)
|
||||
<< lType << rType << lex->getSourceRange() << rex->getSourceRange();
|
||||
}
|
||||
} else {
|
||||
if (lType->isFunctionPointerType() != rType->isFunctionPointerType()) {
|
||||
if (!LHSIsNull && !RHSIsNull)
|
||||
Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers)
|
||||
<< lType << rType << lex->getSourceRange() << rex->getSourceRange();
|
||||
}
|
||||
}
|
||||
|
||||
// Simple check: if the pointee types are identical, we're done.
|
||||
if (LCanPointeeTy == RCanPointeeTy)
|
||||
return ResultTy;
|
||||
|
||||
if (getLangOptions().CPlusPlus) {
|
||||
if (LCanPointeeTy == RCanPointeeTy)
|
||||
return ResultTy;
|
||||
|
||||
// C++ [expr.rel]p2:
|
||||
// [...] Pointer conversions (4.10) and qualification
|
||||
// conversions (4.4) are performed on pointer operands (or on
|
||||
|
@ -4278,15 +4260,29 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
|
|||
ImpCastExprToType(rex, T);
|
||||
return ResultTy;
|
||||
}
|
||||
|
||||
if (!LHSIsNull && !RHSIsNull && // C99 6.5.9p2
|
||||
!LCanPointeeTy->isVoidType() && !RCanPointeeTy->isVoidType() &&
|
||||
!Context.typesAreCompatible(LCanPointeeTy.getUnqualifiedType(),
|
||||
RCanPointeeTy.getUnqualifiedType())) {
|
||||
// C99 6.5.9p2 and C99 6.5.8p2
|
||||
if (Context.typesAreCompatible(LCanPointeeTy.getUnqualifiedType(),
|
||||
RCanPointeeTy.getUnqualifiedType())) {
|
||||
// Valid unless a relational comparison of function pointers
|
||||
if (isRelational && LCanPointeeTy->isFunctionType()) {
|
||||
Diag(Loc, diag::ext_typecheck_ordered_comparison_of_function_pointers)
|
||||
<< lType << rType << lex->getSourceRange() << rex->getSourceRange();
|
||||
}
|
||||
} else if (!isRelational &&
|
||||
(LCanPointeeTy->isVoidType() || RCanPointeeTy->isVoidType())) {
|
||||
// Valid unless comparison between non-null pointer and function pointer
|
||||
if ((LCanPointeeTy->isFunctionType() || RCanPointeeTy->isFunctionType())
|
||||
&& !LHSIsNull && !RHSIsNull) {
|
||||
Diag(Loc, diag::ext_typecheck_comparison_of_fptr_to_void)
|
||||
<< lType << rType << lex->getSourceRange() << rex->getSourceRange();
|
||||
}
|
||||
} else {
|
||||
// Invalid
|
||||
Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers)
|
||||
<< lType << rType << lex->getSourceRange() << rex->getSourceRange();
|
||||
}
|
||||
ImpCastExprToType(rex, lType); // promote the pointer to pointer
|
||||
if (LCanPointeeTy != RCanPointeeTy)
|
||||
ImpCastExprToType(rex, lType); // promote the pointer to pointer
|
||||
return ResultTy;
|
||||
}
|
||||
// C++ allows comparison of pointers with null pointer constants.
|
||||
|
|
|
@ -24,13 +24,15 @@ int pointers(int *a) {
|
|||
return a > (void *)0; // expected-warning {{comparison of distinct pointer types}}
|
||||
}
|
||||
|
||||
int function_pointers(int (*a)(int), int (*b)(int)) {
|
||||
int function_pointers(int (*a)(int), int (*b)(int), void (*c)(int)) {
|
||||
return a > b; // expected-warning {{ordered comparison of function pointers}}
|
||||
return function_pointers > function_pointers; // expected-warning {{ordered comparison of function pointers}}
|
||||
return a > c; // expected-warning {{comparison of distinct pointer types}}
|
||||
return a == (void *) 0;
|
||||
return a == (void *) 1; // expected-warning {{comparison of distinct pointer types}}
|
||||
return a == (void *) 1; // expected-warning {{equality comparison between function pointer and void pointer}}
|
||||
}
|
||||
|
||||
int void_pointers(void *foo) {
|
||||
return foo == NULL;
|
||||
int void_pointers(void* foo) {
|
||||
return foo == (void*) 0;
|
||||
return foo == (void*) 1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue