pestctrl created this revision. pestctrl added a reviewer: rsmith. pestctrl added a project: clang.
Clang is missing one of the conditions for C99 6.5.9p2, where comparison between pointers must either both point to incomplete types or both point to complete types. This patch adds an extra check to the clause where two pointers are of compatible types. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D79945 Files: clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/Sema/SemaExpr.cpp clang/test/Sema/compare.c Index: clang/test/Sema/compare.c =================================================================== --- clang/test/Sema/compare.c +++ clang/test/Sema/compare.c @@ -405,3 +405,12 @@ if (x == y) x = y; // no warning if (y == x) y = x; // no warning } + +int incomplete[]; +int complete[5]; + +void test13() { + if (&incomplete < &complete) { // expected-error {{ordered comparison of complete and incomplete pointers}} + return; + } +} Index: clang/lib/Sema/SemaExpr.cpp =================================================================== --- clang/lib/Sema/SemaExpr.cpp +++ clang/lib/Sema/SemaExpr.cpp @@ -11426,8 +11426,15 @@ // 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()) { + // Pointers both need to point to complete or incomplete types + if (LCanPointeeTy->isIncompleteType() != + RCanPointeeTy->isIncompleteType()) { + Diag(Loc, + diag::err_typecheck_comparison_of_complete_and_incomplete_types) + << LHSType << RHSType << LHS.get()->getSourceRange() + << RHS.get()->getSourceRange(); + } else if (IsRelational && LCanPointeeTy->isFunctionType()) { + // Valid unless a relational comparison of function pointers Diag(Loc, diag::ext_typecheck_ordered_comparison_of_function_pointers) << LHSType << RHSType << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); Index: clang/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticSemaKinds.td +++ clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -6461,6 +6461,8 @@ "ordered comparison between pointer and zero (%0 and %1)">; def err_typecheck_three_way_comparison_of_pointer_and_zero : Error< "three-way comparison between pointer and zero">; +def err_typecheck_comparison_of_complete_and_incomplete_types : Error< + "ordered comparison of complete and incomplete pointers (%0 and %1)">; def ext_typecheck_ordered_comparison_of_function_pointers : ExtWarn< "ordered comparison of function pointers (%0 and %1)">, InGroup<DiagGroup<"ordered-compare-function-pointers">>;
Index: clang/test/Sema/compare.c =================================================================== --- clang/test/Sema/compare.c +++ clang/test/Sema/compare.c @@ -405,3 +405,12 @@ if (x == y) x = y; // no warning if (y == x) y = x; // no warning } + +int incomplete[]; +int complete[5]; + +void test13() { + if (&incomplete < &complete) { // expected-error {{ordered comparison of complete and incomplete pointers}} + return; + } +} Index: clang/lib/Sema/SemaExpr.cpp =================================================================== --- clang/lib/Sema/SemaExpr.cpp +++ clang/lib/Sema/SemaExpr.cpp @@ -11426,8 +11426,15 @@ // 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()) { + // Pointers both need to point to complete or incomplete types + if (LCanPointeeTy->isIncompleteType() != + RCanPointeeTy->isIncompleteType()) { + Diag(Loc, + diag::err_typecheck_comparison_of_complete_and_incomplete_types) + << LHSType << RHSType << LHS.get()->getSourceRange() + << RHS.get()->getSourceRange(); + } else if (IsRelational && LCanPointeeTy->isFunctionType()) { + // Valid unless a relational comparison of function pointers Diag(Loc, diag::ext_typecheck_ordered_comparison_of_function_pointers) << LHSType << RHSType << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); Index: clang/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticSemaKinds.td +++ clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -6461,6 +6461,8 @@ "ordered comparison between pointer and zero (%0 and %1)">; def err_typecheck_three_way_comparison_of_pointer_and_zero : Error< "three-way comparison between pointer and zero">; +def err_typecheck_comparison_of_complete_and_incomplete_types : Error< + "ordered comparison of complete and incomplete pointers (%0 and %1)">; def ext_typecheck_ordered_comparison_of_function_pointers : ExtWarn< "ordered comparison of function pointers (%0 and %1)">, InGroup<DiagGroup<"ordered-compare-function-pointers">>;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits