diff options
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 34 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 7 | ||||
-rw-r--r-- | clang/test/Sema/const-eval.c | 4 |
3 files changed, 38 insertions, 7 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 6a290a6c834..9b9150c148b 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -4333,6 +4333,37 @@ bool ComplexExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) { } //===----------------------------------------------------------------------===// +// Void expression evaluation, primarily for a cast to void on the LHS of a +// comma operator +//===----------------------------------------------------------------------===// + +namespace { +class VoidExprEvaluator + : public ExprEvaluatorBase<VoidExprEvaluator, bool> { +public: + VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {} + + bool Success(const CCValue &V, const Expr *e) { return true; } + bool Error(const Expr *E) { return false; } + + bool VisitCastExpr(const CastExpr *E) { + switch (E->getCastKind()) { + default: + return ExprEvaluatorBaseTy::VisitCastExpr(E); + case CK_ToVoid: + VisitIgnoredValue(E->getSubExpr()); + return true; + } + } +}; +} // end anonymous namespace + +static bool EvaluateVoid(const Expr *E, EvalInfo &Info) { + assert(E->isRValue() && E->getType()->isVoidType()); + return VoidExprEvaluator(Info).Visit(E); +} + +//===----------------------------------------------------------------------===// // Top level Expr::EvaluateAsRValue method. //===----------------------------------------------------------------------===// @@ -4383,6 +4414,9 @@ static bool Evaluate(CCValue &Result, EvalInfo &Info, const Expr *E) { if (!EvaluateRecord(E, LV, Info.CurrentCall->Temporaries[E], Info)) return false; Result = Info.CurrentCall->Temporaries[E]; + } else if (E->getType()->isVoidType()) { + if (!EvaluateVoid(E, Info)) + return false; } else return false; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index cc8ec878ccb..793cbf31bf1 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -18,7 +18,6 @@ #include "clang/Sema/Scope.h" #include "clang/Sema/ScopeInfo.h" #include "TypeLocBuilder.h" -#include "clang/AST/APValue.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" #include "clang/AST/CXXInheritance.h" @@ -3465,14 +3464,12 @@ static QualType TryToFixInvalidVariablyModifiedType(QualType T, if (VLATy->getElementType()->isVariablyModifiedType()) return QualType(); - Expr::EvalResult EvalResult; + llvm::APSInt Res; if (!VLATy->getSizeExpr() || - !VLATy->getSizeExpr()->EvaluateAsRValue(EvalResult, Context) || - !EvalResult.Val.isInt()) + !VLATy->getSizeExpr()->EvaluateAsInt(Res, Context)) return QualType(); // Check whether the array size is negative. - llvm::APSInt &Res = EvalResult.Val.getInt(); if (Res.isSigned() && Res.isNegative()) { SizeIsNegative = true; return QualType(); diff --git a/clang/test/Sema/const-eval.c b/clang/test/Sema/const-eval.c index 8904e12bf7a..a40039bdc5b 100644 --- a/clang/test/Sema/const-eval.c +++ b/clang/test/Sema/const-eval.c @@ -14,9 +14,9 @@ EVAL_EXPR(8, (_Bool)"asdf") EVAL_EXPR(9, !!&x) EVAL_EXPR(10, ((void)1, 12)) void g0(void); -EVAL_EXPR(11, (g0(), 12)) // FIXME: This should give an error +EVAL_EXPR(11, (g0(), 12)) // expected-error {{must have a constant size}} EVAL_EXPR(12, 1.0&&2.0) -EVAL_EXPR(13, x || 3.0) +EVAL_EXPR(13, x || 3.0) // expected-error {{must have a constant size}} unsigned int l_19 = 1; EVAL_EXPR(14, (1 ^ l_19) && 1); // expected-error {{fields must have a constant size}} |