[clang] 4294841 - [clang][ExprConst] Can't be past an invalid LValue designator (#84293)

via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 18 06:56:20 PDT 2024


Author: Timm Baeder
Date: 2024-03-18T14:56:16+01:00
New Revision: 4294841ebcbb22076a24267cdf5164c7aeed9941

URL: https://github.com/llvm/llvm-project/commit/4294841ebcbb22076a24267cdf5164c7aeed9941
DIFF: https://github.com/llvm/llvm-project/commit/4294841ebcbb22076a24267cdf5164c7aeed9941.diff

LOG: [clang][ExprConst] Can't be past an invalid LValue designator (#84293)

For the test case in C, both `LV.getLValueOffset()` and
`Ctx.getTypeSizeInChars(Ty)` are zero, so we return `true` from
`isOnePastTheEndOfCompleteObject()` and ultimately diagnose this as
being one past the end, but the diagnostic doesn't make sense.

Added: 
    clang/test/Sema/constexpr-void-cast.c

Modified: 
    clang/lib/AST/ExprConstant.cpp
    clang/test/AST/Interp/c.c
    clang/test/Sema/const-eval.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 80f49714b64f0f..592d43597dc1b4 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -9253,7 +9253,8 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr *E) {
            Info.getLangOpts().CPlusPlus26)) {
         // Permitted.
       } else {
-        if (SubExpr->getType()->isVoidPointerType()) {
+        if (SubExpr->getType()->isVoidPointerType() &&
+            Info.getLangOpts().CPlusPlus) {
           if (HasValidResult)
             CCEDiag(E, diag::note_constexpr_invalid_void_star_cast)
                 << SubExpr->getType() << Info.getLangOpts().CPlusPlus26
@@ -12942,6 +12943,10 @@ static bool isOnePastTheEndOfCompleteObject(const ASTContext &Ctx,
   if (Ty->isIncompleteType())
     return true;
 
+  // Can't be past the end of an invalid object.
+  if (LV.getLValueDesignator().Invalid)
+    return false;
+
   // We're a past-the-end pointer if we point to the byte after the object,
   // no matter what our type or path is.
   auto Size = Ctx.getTypeSizeInChars(Ty);

diff  --git a/clang/test/AST/Interp/c.c b/clang/test/AST/Interp/c.c
index 5caebd9ce6f14e..10e23839f2ba2a 100644
--- a/clang/test/AST/Interp/c.c
+++ b/clang/test/AST/Interp/c.c
@@ -66,11 +66,11 @@ _Static_assert((&a - 100) != 0, ""); // pedantic-ref-warning {{is a GNU extensio
                                      // pedantic-ref-note {{-100 of non-array}} \
                                      // pedantic-expected-note {{-100 of non-array}}
 /// extern variable of a composite type.
-/// FIXME: The 'cast from void*' note is missing in the new interpreter.
+/// FIXME: The 'this conversion is not allowed' note is missing in the new interpreter.
 extern struct Test50S Test50;
 _Static_assert(&Test50 != (void*)0, ""); // all-warning {{always true}} \
                                          // pedantic-ref-warning {{is a GNU extension}} \
-                                         // pedantic-ref-note {{cast from 'void *' is not allowed}} \
+                                         // pedantic-ref-note {{this conversion is not allowed in a constant expression}} \
                                          // pedantic-expected-warning {{is a GNU extension}}
 
 struct y {int x,y;};

diff  --git a/clang/test/Sema/const-eval.c b/clang/test/Sema/const-eval.c
index 2e38d5e23c208a..e358aceaad5a43 100644
--- a/clang/test/Sema/const-eval.c
+++ b/clang/test/Sema/const-eval.c
@@ -134,8 +134,7 @@ void PR21945(void) { int i = (({}), 0l); }
 
 void PR24622(void);
 struct PR24622 {} pr24622;
-EVAL_EXPR(52, &pr24622 == (void *)&PR24622); // expected-error {{not an integer constant expression}}
-                                             // expected-note at -1 {{past the end}}
+EVAL_EXPR(52, &pr24622 == (void *)&PR24622);
 
 // We evaluate these by providing 2s' complement semantics in constant
 // expressions, like we do for integers.

diff  --git a/clang/test/Sema/constexpr-void-cast.c b/clang/test/Sema/constexpr-void-cast.c
new file mode 100644
index 00000000000000..c5caa3b9e58feb
--- /dev/null
+++ b/clang/test/Sema/constexpr-void-cast.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -x c -fsyntax-only %s -verify=c
+// RUN: %clang_cc1 -x c -fsyntax-only %s -pedantic -verify=c-pedantic
+//
+// RUN: %clang_cc1 -x c++ -fsyntax-only %s -verify=cxx
+// RUN: %clang_cc1 -x c++ -fsyntax-only %s -pedantic -verify=cxx-pedantic
+
+// c-no-diagnostics
+// cxx-no-diagnostics
+
+void f(void);
+struct S {char c;} s;
+_Static_assert(&s != (void *)&f, ""); // c-pedantic-warning {{not an integer constant expression}} \
+                                      // c-pedantic-note {{this conversion is not allowed in a constant expression}} \
+                                      // cxx-pedantic-warning {{'_Static_assert' is a C11 extension}}


        


More information about the cfe-commits mailing list