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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits