[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