summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/AST/ExprConstant.cpp34
-rw-r--r--clang/lib/Sema/SemaDecl.cpp7
-rw-r--r--clang/test/Sema/const-eval.c4
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}}
OpenPOWER on IntegriCloud