-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang][ExprConst] Can't be past an invalid LValue designator #84293
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) ChangesFor the test case in C, both Full diff: https://github.com/llvm/llvm-project/pull/84293.diff 3 Files Affected:
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@-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}}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Precommit CI seems to have found relevant failures
e393a6a
to
8dda4c1
Compare
Ping |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
…4293) 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.
For the test case in C, both
LV.getLValueOffset()
andCtx.getTypeSizeInChars(Ty)
are zero, so we returntrue
fromisOnePastTheEndOfCompleteObject()
and ultimately diagnose this as being one past the end, but the diagnostic doesn't make sense.