Author: efriedma Date: Sat Aug 22 19:27:47 2009 New Revision: 79793 URL: http://llvm.org/viewvc/llvm-project?rev=79793&view=rev Log: Catch a few more cases of illegal comparisons.
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/Sema/SemaExpr.cpp cfe/trunk/test/Sema/compare.c Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=79793&r1=79792&r2=79793&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sat Aug 22 19:27:47 2009 @@ -1352,6 +1352,8 @@ "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< Modified: cfe/trunk/lib/Sema/SemaExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=79793&r1=79792&r2=79793&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) +++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Aug 22 19:27:47 2009 @@ -4237,28 +4237,10 @@ 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 @@ 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. Modified: cfe/trunk/test/Sema/compare.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/compare.c?rev=79793&r1=79792&r2=79793&view=diff ============================================================================== --- cfe/trunk/test/Sema/compare.c (original) +++ cfe/trunk/test/Sema/compare.c Sat Aug 22 19:27:47 2009 @@ -24,13 +24,15 @@ 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; } _______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits