[clang] 181e4c6 - [clang][Interp] Check for non-primitive types in unary operators
Timm Bäder via cfe-commits
cfe-commits at lists.llvm.org
Sun Jul 14 01:48:19 PDT 2024
Author: Timm Bäder
Date: 2024-07-14T10:47:51+02:00
New Revision: 181e4c6291c94a38c0ee89d2128f8d70b15d2d23
URL: https://github.com/llvm/llvm-project/commit/181e4c6291c94a38c0ee89d2128f8d70b15d2d23
DIFF: https://github.com/llvm/llvm-project/commit/181e4c6291c94a38c0ee89d2128f8d70b15d2d23.diff
LOG: [clang][Interp] Check for non-primitive types in unary operators
For invalid cases (non-vector/complex/...), this should only happen
in error cases such as the attached test case.
Added:
Modified:
clang/lib/AST/Interp/Compiler.cpp
clang/test/AST/Interp/literals.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/Interp/Compiler.cpp b/clang/lib/AST/Interp/Compiler.cpp
index c58eb2eaa477..30dc7f5e4840 100644
--- a/clang/lib/AST/Interp/Compiler.cpp
+++ b/clang/lib/AST/Interp/Compiler.cpp
@@ -4706,6 +4706,8 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
case UO_PostInc: { // x++
if (!Ctx.getLangOpts().CPlusPlus14)
return this->emitInvalid(E);
+ if (!T)
+ return this->emitError(E);
if (!this->visit(SubExpr))
return false;
@@ -4727,6 +4729,8 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
case UO_PostDec: { // x--
if (!Ctx.getLangOpts().CPlusPlus14)
return this->emitInvalid(E);
+ if (!T)
+ return this->emitError(E);
if (!this->visit(SubExpr))
return false;
@@ -4748,6 +4752,8 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
case UO_PreInc: { // ++x
if (!Ctx.getLangOpts().CPlusPlus14)
return this->emitInvalid(E);
+ if (!T)
+ return this->emitError(E);
if (!this->visit(SubExpr))
return false;
@@ -4795,6 +4801,8 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
case UO_PreDec: { // --x
if (!Ctx.getLangOpts().CPlusPlus14)
return this->emitInvalid(E);
+ if (!T)
+ return this->emitError(E);
if (!this->visit(SubExpr))
return false;
@@ -4840,6 +4848,9 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
return E->isGLValue() || this->emitLoadPop(*T, E);
}
case UO_LNot: // !x
+ if (!T)
+ return this->emitError(E);
+
if (DiscardResult)
return this->discard(SubExpr);
@@ -4853,10 +4864,16 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
return this->emitCast(PT_Bool, ET, E);
return true;
case UO_Minus: // -x
+ if (!T)
+ return this->emitError(E);
+
if (!this->visit(SubExpr))
return false;
return DiscardResult ? this->emitPop(*T, E) : this->emitNeg(*T, E);
case UO_Plus: // +x
+ if (!T)
+ return this->emitError(E);
+
if (!this->visit(SubExpr)) // noop
return false;
return DiscardResult ? this->emitPop(*T, E) : true;
@@ -4873,6 +4890,9 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
return this->discard(SubExpr);
return this->visit(SubExpr);
case UO_Not: // ~x
+ if (!T)
+ return this->emitError(E);
+
if (!this->visit(SubExpr))
return false;
return DiscardResult ? this->emitPop(*T, E) : this->emitComp(*T, E);
diff --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp
index 1f2755e710e3..93e7e8b52a45 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -1290,3 +1290,13 @@ namespace NTTP {
return size(Chars);
}
}
+
+#if __cplusplus >= 201402L
+namespace UnaryOpError {
+ constexpr int foo() {
+ int f = 0;
+ ++g; // both-error {{use of undeclared identifier 'g'}}
+ return f;
+ }
+}
+#endif
More information about the cfe-commits
mailing list