[cfe-commits] r59884 - in /cfe/trunk: include/clang/AST/Expr.h lib/AST/ExprConstant.cpp lib/Sema/SemaStmt.cpp test/Sema/switch.c
Anders Carlsson
andersca at mac.com
Sat Nov 22 13:50:50 PST 2008
Author: andersca
Date: Sat Nov 22 15:50:49 2008
New Revision: 59884
URL: http://llvm.org/viewvc/llvm-project?rev=59884&view=rev
Log:
Case values must be evaluated
Modified:
cfe/trunk/include/clang/AST/Expr.h
cfe/trunk/lib/AST/ExprConstant.cpp
cfe/trunk/lib/Sema/SemaStmt.cpp
cfe/trunk/test/Sema/switch.c
Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=59884&r1=59883&r2=59884&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Sat Nov 22 15:50:49 2008
@@ -141,8 +141,9 @@
/// any crazy technique (that has nothing to do with language standards) that
/// we want to. If this function returns true, it returns the folded constant
/// in Result.
- bool Evaluate(APValue& Result, ASTContext &Ctx) const;
-
+ // FIXME: We should come up with a better API for the isEvaluated case.
+ bool Evaluate(APValue& Result, ASTContext &Ctx, bool *isEvaluated = 0) const;
+
/// isEvaluatable - Call Evaluate to see if this expression can be constant
/// folded, but discard the result.
bool isEvaluatable(ASTContext &Ctx) const;
Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=59884&r1=59883&r2=59884&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Sat Nov 22 15:50:49 2008
@@ -537,6 +537,7 @@
// These need to be handled specially because the operands aren't
// necessarily integral
bool bres;
+ bool isEvaluated = true;
if (HandleConversionToBool(E->getLHS(), bres, Info)) {
// We were able to evaluate the LHS, see if we can get away with not
@@ -548,16 +549,18 @@
// We can't evaluate.
return false;
}
+
+ // We did not evaluate the LHS
+ isEvaluated = false;
}
- // FIXME: If we evaluate the RHS, we need to check if the LHS has
- // any side effects.
-
if (bres == (E->getOpcode() == BinaryOperator::LOr) ||
!bres == (E->getOpcode() == BinaryOperator::LAnd)) {
Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
Result = bres;
+ Info.isEvaluated = isEvaluated;
+
return true;
}
@@ -1153,30 +1156,31 @@
/// any crazy technique (that has nothing to do with language standards) that
/// we want to. If this function returns true, it returns the folded constant
/// in Result.
-bool Expr::Evaluate(APValue &Result, ASTContext &Ctx) const {
+bool Expr::Evaluate(APValue &Result, ASTContext &Ctx, bool *isEvaluated) const {
EvalInfo Info(Ctx);
if (getType()->isIntegerType()) {
llvm::APSInt sInt(32);
- if (EvaluateInteger(this, sInt, Info)) {
- Result = APValue(sInt);
- return true;
- }
+ if (!EvaluateInteger(this, sInt, Info))
+ return false;
+
+ Result = APValue(sInt);
} else if (getType()->isPointerType()) {
- if (EvaluatePointer(this, Result, Info)) {
- return true;
- }
+ if (!EvaluatePointer(this, Result, Info))
+ return false;
} else if (getType()->isRealFloatingType()) {
llvm::APFloat f(0.0);
- if (EvaluateFloat(this, f, Info)) {
- Result = APValue(f);
- return true;
- }
+ if (!EvaluateFloat(this, f, Info))
+ return false;
+
+ Result = APValue(f);
} else if (getType()->isComplexType()) {
- if (EvaluateComplexFloat(this, Result, Info))
- return true;
+ if (!EvaluateComplexFloat(this, Result, Info))
+ return false;
}
-
- return false;
+
+ if (isEvaluated)
+ *isEvaluated = Info.isEvaluated;
+ return true;
}
/// isEvaluatable - Call Evaluate to see if this expression can be constant
Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=59884&r1=59883&r2=59884&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Sat Nov 22 15:50:49 2008
@@ -131,8 +131,10 @@
// However, GCC allows any evaluatable integer expression.
// FIXME: Should we warn if this is evaluatable but not an I-C-E?
APValue Result;
+ bool isEvaluated;
- if (!LHSVal->Evaluate(Result, Context) || !Result.isInt()) {
+ if (!LHSVal->Evaluate(Result, Context, &isEvaluated) || !Result.isInt() ||
+ !isEvaluated) {
// FIXME: Evaluate doesn't return the SourceLocation that it failed to
// evaluate.
ExpLoc = LHSVal->getExprLoc();
@@ -142,7 +144,8 @@
}
// GCC extension: The expression shall be an integer constant.
- if (RHSVal && !RHSVal->Evaluate(Result, Context) || !Result.isInt()) {
+ if (RHSVal && !RHSVal->Evaluate(Result, Context, &isEvaluated) ||
+ !Result.isInt() || !isEvaluated) {
ExpLoc = RHSVal->getExprLoc();
Diag(ExpLoc, diag::err_case_label_not_integer_constant_expr)
<< RHSVal->getSourceRange();
Modified: cfe/trunk/test/Sema/switch.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/switch.c?rev=59884&r1=59883&r2=59884&view=diff
==============================================================================
--- cfe/trunk/test/Sema/switch.c (original)
+++ cfe/trunk/test/Sema/switch.c Sat Nov 22 15:50:49 2008
@@ -48,5 +48,15 @@
case 0 && g() ... 1 || g():
break;
}
+
+ switch (1) {
+ case g() && 0: // expected-error {{case label does not reduce to an integer constant}}
+ break;
+ }
+
+ switch (1) {
+ case 0 ... g() || 1: // expected-error {{case label does not reduce to an integer constant}}
+ break;
+ }
}
More information about the cfe-commits
mailing list