summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-01-24 19:08:01 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-01-24 19:08:01 +0000
commit134a02586e25f60811096c038492f4c8e17917da (patch)
treec99e077c42c6e6bc6799049137b93c9cb3536c27
parenta0b892113a9977575b3ca647339225c0302cfeee (diff)
downloadbcm5719-llvm-134a02586e25f60811096c038492f4c8e17917da.tar.gz
bcm5719-llvm-134a02586e25f60811096c038492f4c8e17917da.zip
Fix invalid evaluation of _Complex float (real & imaginary parts had
mismatched semantics). - Enforce this in APValue. llvm-svn: 62924
-rw-r--r--clang/include/clang/AST/APValue.h4
-rw-r--r--clang/lib/AST/ExprConstant.cpp10
-rw-r--r--clang/test/Sema/const-eval.c3
3 files changed, 15 insertions, 2 deletions
diff --git a/clang/include/clang/AST/APValue.h b/clang/include/clang/AST/APValue.h
index d88757de1a3..5d5abfe011d 100644
--- a/clang/include/clang/AST/APValue.h
+++ b/clang/include/clang/AST/APValue.h
@@ -188,11 +188,15 @@ public:
((Vec*)(void*)Data)->Elts[i] = E[i];
}
void setComplexInt(const APSInt &R, const APSInt &I) {
+ assert(R.getBitWidth() == I.getBitWidth() &&
+ "Invalid complex int (type mismatch).");
assert(isComplexInt() && "Invalid accessor");
((ComplexAPSInt*)(void*)Data)->Real = R;
((ComplexAPSInt*)(void*)Data)->Imag = I;
}
void setComplexFloat(const APFloat &R, const APFloat &I) {
+ assert(&R.getSemantics() == &I.getSemantics() &&
+ "Invalid complex float (type mismatch).");
assert(isComplexFloat() && "Invalid accessor");
((ComplexAPFloat*)(void*)Data)->Real = R;
((ComplexAPFloat*)(void*)Data)->Imag = I;
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index f45bd787b56..16c6e89c329 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -1194,7 +1194,8 @@ public:
if (!EvaluateFloat(E->getSubExpr(), Result, Info))
return APValue();
- return APValue(APFloat(0.0), Result);
+ return APValue(APFloat(Result.getSemantics(), APFloat::fcZero),
+ Result);
}
APValue VisitCastExpr(CastExpr *E) {
@@ -1206,7 +1207,8 @@ public:
if (!EvaluateFloat(SubExpr, Result, Info))
return APValue();
- return APValue(Result, APFloat(0.0));
+ return APValue(Result,
+ APFloat(Result.getSemantics(), APFloat::fcZero));
}
// FIXME: Handle more casts.
@@ -1221,6 +1223,10 @@ public:
static bool EvaluateComplexFloat(const Expr *E, APValue &Result, EvalInfo &Info)
{
Result = ComplexFloatExprEvaluator(Info).Visit(const_cast<Expr*>(E));
+ if (Result.isComplexFloat())
+ assert(&Result.getComplexFloatReal().getSemantics() ==
+ &Result.getComplexFloatImag().getSemantics() &&
+ "Invalid complex evaluation.");
return Result.isComplexFloat();
}
diff --git a/clang/test/Sema/const-eval.c b/clang/test/Sema/const-eval.c
index e3d63ca94fb..71f76228d1b 100644
--- a/clang/test/Sema/const-eval.c
+++ b/clang/test/Sema/const-eval.c
@@ -26,3 +26,6 @@ void f()
int a;
EVAL_EXPR(15, (_Bool)&a); // expected-error {{fields must have a constant size}}
}
+
+// FIXME: Turn into EVAL_EXPR test once we have more folding.
+_Complex float g16 = (1.0f + 1.0fi);
OpenPOWER on IntegriCloud