Author: Richard Smith Date: 2019-12-16T17:49:45-08:00 New Revision: 4e9f1379b9cd7ddce8cf182707e976ebceb72b05
URL: https://github.com/llvm/llvm-project/commit/4e9f1379b9cd7ddce8cf182707e976ebceb72b05 DIFF: https://github.com/llvm/llvm-project/commit/4e9f1379b9cd7ddce8cf182707e976ebceb72b05.diff LOG: If constant evaluation fails due to an unspecified pointer comparison, produce a note saying that rather than the default "evaluation failed" note. Added: Modified: clang/include/clang/Basic/DiagnosticASTKinds.td clang/lib/AST/ExprConstant.cpp clang/test/CXX/expr/expr.const/p2-0x.cpp clang/test/SemaCXX/constant-expression-cxx11.cpp clang/test/SemaCXX/constant-expression-cxx2a.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td b/clang/include/clang/Basic/DiagnosticASTKinds.td index 814e1e61bd74..25f11213ba55 100644 --- a/clang/include/clang/Basic/DiagnosticASTKinds.td +++ b/clang/include/clang/Basic/DiagnosticASTKinds.td @@ -70,6 +70,8 @@ def note_constexpr_pointer_subtraction_not_same_array : Note< "subtracted pointers are not elements of the same array">; def note_constexpr_pointer_subtraction_zero_size : Note< "subtraction of pointers to type %0 of zero size">; +def note_constexpr_pointer_comparison_unspecified : Note< + "comparison has unspecified value">; def note_constexpr_pointer_comparison_base_classes : Note< "comparison of addresses of subobjects of diff erent base classes " "has unspecified value">; diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index f3856f58b113..9b6d0cb59b0b 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -11625,8 +11625,10 @@ EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E, if (!HasSameBase(LHSValue, RHSValue)) { // Inequalities and subtractions between unrelated pointers have // unspecified or undefined behavior. - if (!IsEquality) - return Error(E); + if (!IsEquality) { + Info.FFDiag(E, diag::note_constexpr_pointer_comparison_unspecified); + return false; + } // A constant address may compare equal to the address of a symbol. // The one exception is that address of an object cannot compare equal // to a null pointer constant. diff --git a/clang/test/CXX/expr/expr.const/p2-0x.cpp b/clang/test/CXX/expr/expr.const/p2-0x.cpp index e84753759c90..cc6380e044fb 100644 --- a/clang/test/CXX/expr/expr.const/p2-0x.cpp +++ b/clang/test/CXX/expr/expr.const/p2-0x.cpp @@ -472,22 +472,22 @@ namespace UnspecifiedRelations { // diff erent objects that are not members of the same array or to diff erent // functions, or if only one of them is null, the results of p<q, p>q, p<=q, // and p>=q are unspecified. - constexpr bool u1 = p < q; // expected-error {{constant expression}} - constexpr bool u2 = p > q; // expected-error {{constant expression}} - constexpr bool u3 = p <= q; // expected-error {{constant expression}} - constexpr bool u4 = p >= q; // expected-error {{constant expression}} - constexpr bool u5 = p < (int*)0; // expected-error {{constant expression}} - constexpr bool u6 = p <= (int*)0; // expected-error {{constant expression}} - constexpr bool u7 = p > (int*)0; // expected-error {{constant expression}} - constexpr bool u8 = p >= (int*)0; // expected-error {{constant expression}} - constexpr bool u9 = (int*)0 < q; // expected-error {{constant expression}} - constexpr bool u10 = (int*)0 <= q; // expected-error {{constant expression}} - constexpr bool u11 = (int*)0 > q; // expected-error {{constant expression}} - constexpr bool u12 = (int*)0 >= q; // expected-error {{constant expression}} + constexpr bool u1 = p < q; // expected-error {{constant expression}} expected-note {{comparison has unspecified value}} + constexpr bool u2 = p > q; // expected-error {{constant expression}} expected-note {{comparison has unspecified value}} + constexpr bool u3 = p <= q; // expected-error {{constant expression}} expected-note {{comparison has unspecified value}} + constexpr bool u4 = p >= q; // expected-error {{constant expression}} expected-note {{comparison has unspecified value}} + constexpr bool u5 = p < (int*)0; // expected-error {{constant expression}} expected-note {{comparison has unspecified value}} + constexpr bool u6 = p <= (int*)0; // expected-error {{constant expression}} expected-note {{comparison has unspecified value}} + constexpr bool u7 = p > (int*)0; // expected-error {{constant expression}} expected-note {{comparison has unspecified value}} + constexpr bool u8 = p >= (int*)0; // expected-error {{constant expression}} expected-note {{comparison has unspecified value}} + constexpr bool u9 = (int*)0 < q; // expected-error {{constant expression}} expected-note {{comparison has unspecified value}} + constexpr bool u10 = (int*)0 <= q; // expected-error {{constant expression}} expected-note {{comparison has unspecified value}} + constexpr bool u11 = (int*)0 > q; // expected-error {{constant expression}} expected-note {{comparison has unspecified value}} + constexpr bool u12 = (int*)0 >= q; // expected-error {{constant expression}} expected-note {{comparison has unspecified value}} void f(), g(); constexpr void (*pf)() = &f, (*pg)() = &g; - constexpr bool u13 = pf < pg; // expected-error {{constant expression}} + constexpr bool u13 = pf < pg; // expected-error {{constant expression}} expected-note {{comparison has unspecified value}} constexpr bool u14 = pf == pg; // If two pointers point to non-static data members of the same object with @@ -538,11 +538,11 @@ namespace UnspecifiedRelations { constexpr void *pv = (void*)&s.a; constexpr void *qv = (void*)&s.b; constexpr bool v1 = null < (int*)0; - constexpr bool v2 = null < pv; // expected-error {{constant expression}} + constexpr bool v2 = null < pv; // expected-error {{constant expression}} expected-note {{comparison has unspecified value}} constexpr bool v3 = null == pv; // ok constexpr bool v4 = qv == pv; // ok constexpr bool v5 = qv >= pv; // expected-error {{constant expression}} expected-note {{unequal pointers to void}} - constexpr bool v6 = qv > null; // expected-error {{constant expression}} + constexpr bool v6 = qv > null; // expected-error {{constant expression}} expected-note {{comparison has unspecified value}} constexpr bool v7 = qv <= (void*)&s.b; // ok constexpr bool v8 = qv > (void*)&s.a; // expected-error {{constant expression}} expected-note {{unequal pointers to void}} } diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp index 27ad0f654f56..7d8b67daa403 100644 --- a/clang/test/SemaCXX/constant-expression-cxx11.cpp +++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp @@ -283,10 +283,10 @@ static_assert(&x == &y, "false"); // expected-error {{false}} static_assert(&x != &y, ""); constexpr bool g1 = &x == &y; constexpr bool g2 = &x != &y; -constexpr bool g3 = &x <= &y; // expected-error {{must be initialized by a constant expression}} -constexpr bool g4 = &x >= &y; // expected-error {{must be initialized by a constant expression}} -constexpr bool g5 = &x < &y; // expected-error {{must be initialized by a constant expression}} -constexpr bool g6 = &x > &y; // expected-error {{must be initialized by a constant expression}} +constexpr bool g3 = &x <= &y; // expected-error {{must be initialized by a constant expression}} expected-note {{unspecified}} +constexpr bool g4 = &x >= &y; // expected-error {{must be initialized by a constant expression}} expected-note {{unspecified}} +constexpr bool g5 = &x < &y; // expected-error {{must be initialized by a constant expression}} expected-note {{unspecified}} +constexpr bool g6 = &x > &y; // expected-error {{must be initialized by a constant expression}} expected-note {{unspecified}} struct S { int x, y; } s; static_assert(&s.x == &s.y, "false"); // expected-error {{false}} @@ -298,17 +298,17 @@ static_assert(&s.x > &s.y, "false"); // expected-error {{false}} static_assert(0 == &y, "false"); // expected-error {{false}} static_assert(0 != &y, ""); -constexpr bool n3 = (int*)0 <= &y; // expected-error {{must be initialized by a constant expression}} -constexpr bool n4 = (int*)0 >= &y; // expected-error {{must be initialized by a constant expression}} -constexpr bool n5 = (int*)0 < &y; // expected-error {{must be initialized by a constant expression}} -constexpr bool n6 = (int*)0 > &y; // expected-error {{must be initialized by a constant expression}} +constexpr bool n3 = (int*)0 <= &y; // expected-error {{must be initialized by a constant expression}} expected-note {{unspecified}} +constexpr bool n4 = (int*)0 >= &y; // expected-error {{must be initialized by a constant expression}} expected-note {{unspecified}} +constexpr bool n5 = (int*)0 < &y; // expected-error {{must be initialized by a constant expression}} expected-note {{unspecified}} +constexpr bool n6 = (int*)0 > &y; // expected-error {{must be initialized by a constant expression}} expected-note {{unspecified}} static_assert(&x == 0, "false"); // expected-error {{false}} static_assert(&x != 0, ""); -constexpr bool n9 = &x <= (int*)0; // expected-error {{must be initialized by a constant expression}} -constexpr bool n10 = &x >= (int*)0; // expected-error {{must be initialized by a constant expression}} -constexpr bool n11 = &x < (int*)0; // expected-error {{must be initialized by a constant expression}} -constexpr bool n12 = &x > (int*)0; // expected-error {{must be initialized by a constant expression}} +constexpr bool n9 = &x <= (int*)0; // expected-error {{must be initialized by a constant expression}} expected-note {{unspecified}} +constexpr bool n10 = &x >= (int*)0; // expected-error {{must be initialized by a constant expression}} expected-note {{unspecified}} +constexpr bool n11 = &x < (int*)0; // expected-error {{must be initialized by a constant expression}} expected-note {{unspecified}} +constexpr bool n12 = &x > (int*)0; // expected-error {{must be initialized by a constant expression}} expected-note {{unspecified}} static_assert(&x == &x, ""); static_assert(&x != &x, "false"); // expected-error {{false}} diff --git a/clang/test/SemaCXX/constant-expression-cxx2a.cpp b/clang/test/SemaCXX/constant-expression-cxx2a.cpp index c2e443b9bec1..3cd16d8216fb 100644 --- a/clang/test/SemaCXX/constant-expression-cxx2a.cpp +++ b/clang/test/SemaCXX/constant-expression-cxx2a.cpp @@ -174,7 +174,7 @@ constexpr bool test_constexpr() { using nullptr_t = decltype(nullptr); using LHSTy = decltype(LHS); using RHSTy = decltype(RHS); - // expected-note@+1 {{subexpression not valid in a constant expression}} + // expected-note@+1 {{unspecified}} auto Res = (LHS <=> RHS); if constexpr (__is_same(LHSTy, nullptr_t) || __is_same(RHSTy, nullptr_t)) { CHECK_TYPE(decltype(Res), std::strong_equality); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits