[clang] [clang][ExprConst] Can't be past an invalid LValue designator (PR #84293)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Mar 7 01:28:16 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Timm Baeder (tbaederr)
<details>
<summary>Changes</summary>
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.
---
Full diff: https://github.com/llvm/llvm-project/pull/84293.diff
3 Files Affected:
- (modified) clang/lib/AST/ExprConstant.cpp (+6-1)
- (modified) clang/test/Sema/const-eval.c (+1-2)
- (added) clang/test/Sema/constexpr-void-cast.c (+14)
``````````diff
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index d8ca35740fbc35..bc8de9d08542cd 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -9211,7 +9211,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
@@ -12899,6 +12900,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/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}}
``````````
</details>
https://github.com/llvm/llvm-project/pull/84293
More information about the cfe-commits
mailing list