[clang] [clang][ExprConst] Can't be past an invalid LValue designator (PR #84293)
https://github.com/tbaederr closed https://github.com/llvm/llvm-project/pull/84293 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExprConst] Can't be past an invalid LValue designator (PR #84293)
https://github.com/AaronBallman approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/84293 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExprConst] Can't be past an invalid LValue designator (PR #84293)
tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/84293 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExprConst] Can't be past an invalid LValue designator (PR #84293)
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/84293 >From 8dda4c1d6186c8d0ecd6b233f1bd636133056f02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Thu, 7 Mar 2024 10:14:03 +0100 Subject: [PATCH] [clang][ExprConst] Can't be past an invalid LValue designator --- clang/lib/AST/ExprConstant.cpp| 7 ++- clang/test/AST/Interp/c.c | 4 ++-- clang/test/Sema/const-eval.c | 3 +-- clang/test/Sema/constexpr-void-cast.c | 14 ++ 4 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 clang/test/Sema/constexpr-void-cast.c 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 , 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 8de6139efbea09..bd6a5d458b61ac 100644 --- a/clang/test/AST/Interp/c.c +++ b/clang/test/AST/Interp/c.c @@ -66,11 +66,11 @@ _Static_assert(( - 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( != (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, == (void *)); // expected-error {{not an integer constant expression}} - // expected-note@-1 {{past the end}} +EVAL_EXPR(52, == (void *)); // 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 00..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( != (void *), ""); // 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}} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExprConst] Can't be past an invalid LValue designator (PR #84293)
https://github.com/AaronBallman commented: Precommit CI seems to have found relevant failures https://github.com/llvm/llvm-project/pull/84293 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExprConst] Can't be past an invalid LValue designator (PR #84293)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) Changes 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 , 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, == (void *)); // expected-error {{not an integer constant expression}} - // expected-note@-1 {{past the end}} +EVAL_EXPR(52, == (void *)); // 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 00..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( != (void *), ""); // 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}} `` https://github.com/llvm/llvm-project/pull/84293 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExprConst] Can't be past an invalid LValue designator (PR #84293)
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/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. >From e393a6a7ae875eab1154762b1d5bb673adfb9f2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Thu, 7 Mar 2024 10:14:03 +0100 Subject: [PATCH] [clang][ExprConst] Can't be past an invalid LValue designator --- clang/lib/AST/ExprConstant.cpp| 7 ++- clang/test/Sema/const-eval.c | 3 +-- clang/test/Sema/constexpr-void-cast.c | 14 ++ 3 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 clang/test/Sema/constexpr-void-cast.c 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 , 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, == (void *)); // expected-error {{not an integer constant expression}} - // expected-note@-1 {{past the end}} +EVAL_EXPR(52, == (void *)); // 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 00..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( != (void *), ""); // 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}} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits