[cfe-commits] r39454 - in /cfe/cfe/trunk: AST/Expr.cpp AST/SemaDecl.cpp AST/SemaStmt.cpp AST/Type.cpp Sema/SemaDecl.cpp Sema/SemaStmt.cpp include/clang/AST/Expr.h include/clang/AST/Type.h
Steve Naroff
snaroff at apple.com
Wed Jul 11 09:44:37 PDT 2007
Author: snaroff
Date: Wed Jul 11 11:44:36 2007
New Revision: 39454
URL: http://llvm.org/viewvc/llvm-project?rev=39454&view=rev
Log:
Bug #:
Submitted by:
Reviewed by:
Extended Expr's constant expression predicates to return a source location
if the predicate returns false. This enables us to position the cursor
exactly were the error occurred (simple pleasures:-).
constant.c:9:9: error: enumerator value for 'E2' is not an integer constant
E2 = (aconst + 1), // illegal
^
constant.c:10:8: error: enumerator value for 'E3' is not an integer constant
E3 = "abc",
^
constant.c:12:12: error: enumerator value for 'E5' is not an integer constant
E5 = 0?7:printf("xx"), // illegal
^
constant.c:13:12: error: enumerator value for 'E6' is not an integer constant
E6 = 1?7:printf("xx"), // legal
^
constant.c:16:14: error: enumerator value for 'E9' is not an integer constant
E9 = E0 || a, // illegal
^
constant.c:21:6: error: array has incomplete element type 'void'
void ary[7];
^
constant.c:22:28: error: variable length array declared outside of any function
struct { int a; } ary2[1?7:printf("xx")],
^
constant.c:23:34: error: variable length array declared outside of any function
aryIllegal[0?7:printf("yy")];
^
constant.c:25:10: error: variable length array declared outside of any function
int ary3[a]; // illegal
^
constant.c:26:17: error: size of array has non-integer type 'float'
typedef int vla[2.0]; // illegal
^
constant.c:30:22: error: size of array has non-integer type 'float'
int nonIntegerArray2[1+2.0];
^
Modified:
cfe/cfe/trunk/AST/Expr.cpp
cfe/cfe/trunk/AST/SemaDecl.cpp
cfe/cfe/trunk/AST/SemaStmt.cpp
cfe/cfe/trunk/AST/Type.cpp
cfe/cfe/trunk/Sema/SemaDecl.cpp
cfe/cfe/trunk/Sema/SemaStmt.cpp
cfe/cfe/trunk/include/clang/AST/Expr.h
cfe/cfe/trunk/include/clang/AST/Type.h
Modified: cfe/cfe/trunk/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Expr.cpp?rev=39454&r1=39453&r2=39454&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/Expr.cpp (original)
+++ cfe/cfe/trunk/AST/Expr.cpp Wed Jul 11 11:44:36 2007
@@ -192,60 +192,76 @@
/// violation. FIXME: This routine currently implements C90 semantics.
/// To properly implement C99 semantics this routine will need to evaluate
/// expressions involving operators previously mentioned.
-bool Expr::isConstantExpr(bool isIntConst) const {
+bool Expr::isConstantExpr(bool isIntConst, SourceLocation &loc) const {
switch (getStmtClass()) {
case IntegerLiteralClass:
case CharacterLiteralClass:
return true;
case FloatingLiteralClass:
case StringLiteralClass:
- return isIntConst ? false : true;
+ if (!isIntConst)
+ return true;
+ loc = getLocStart();
+ return false;
case DeclRefExprClass:
- return isa<EnumConstantDecl>(cast<DeclRefExpr>(this)->getDecl());
+ if (isa<EnumConstantDecl>(cast<DeclRefExpr>(this)->getDecl()))
+ return true;
+ loc = getLocStart();
+ return false;
case UnaryOperatorClass:
const UnaryOperator *uop = cast<UnaryOperator>(this);
- if (uop->isIncrementDecrementOp()) // C99 6.6p3
+ if (uop->isIncrementDecrementOp()) { // C99 6.6p3
+ loc = getLocStart();
return false;
+ }
// C99 6.5.3.4p2: otherwise, the operand is *not* evaluated and the result
// is an integer constant. This effective ignores any subexpression that
// isn't actually a constant expression (what an odd language:-)
if (uop->isSizeOfAlignOfOp())
- return uop->getSubExpr()->getType()->isConstantSizeType();
- return uop->getSubExpr()->isConstantExpr(isIntConst);
+ return uop->getSubExpr()->getType()->isConstantSizeType(loc);
+ return uop->getSubExpr()->isConstantExpr(isIntConst, loc);
case BinaryOperatorClass:
const BinaryOperator *bop = cast<BinaryOperator>(this);
// C99 6.6p3: shall not contain assignment, increment/decrement,
// function call, or comma operators, *except* when they are contained
// within a subexpression that is not evaluated.
- if (bop->isAssignmentOp() || bop->getOpcode() == BinaryOperator::Comma)
+ if (bop->isAssignmentOp() || bop->getOpcode() == BinaryOperator::Comma) {
+ loc = getLocStart();
return false;
- return bop->getLHS()->isConstantExpr(isIntConst) &&
- bop->getRHS()->isConstantExpr(isIntConst);
+ }
+ return bop->getLHS()->isConstantExpr(isIntConst, loc) &&
+ bop->getRHS()->isConstantExpr(isIntConst, loc);
case ParenExprClass:
- return cast<ParenExpr>(this)->getSubExpr()->isConstantExpr();
+ return cast<ParenExpr>(this)->getSubExpr()->isConstantExpr(isIntConst, loc);
case CastExprClass:
const CastExpr *castExpr = cast<CastExpr>(this);
// C99 6.6p6: shall only convert arithmetic types to integer types.
- if (!castExpr->getSubExpr()->getType()->isArithmeticType())
+ if (!castExpr->getSubExpr()->getType()->isArithmeticType()) {
+ loc = castExpr->getSubExpr()->getLocStart();
+ return false;
+ }
+ if (!castExpr->getDestType()->isIntegerType()) {
+ loc = getLocStart();
return false;
- if (!castExpr->getDestType()->isIntegerType())
- return false;
+ }
// allow floating constants that are the immediate operands of casts.
- if (castExpr->getSubExpr()->isConstantExpr() ||
+ if (castExpr->getSubExpr()->isConstantExpr(isIntConst, loc) ||
isa<FloatingLiteral>(castExpr->getSubExpr()))
return true;
+ loc = getLocStart();
return false;
case SizeOfAlignOfTypeExprClass:
const SizeOfAlignOfTypeExpr *sizeExpr = cast<SizeOfAlignOfTypeExpr>(this);
if (sizeExpr->isSizeOf())
- return sizeExpr->getArgumentType()->isConstantSizeType();
+ return sizeExpr->getArgumentType()->isConstantSizeType(loc);
return true; // alignof will always evaluate to a constant
case ConditionalOperatorClass:
const ConditionalOperator *condExpr = cast<ConditionalOperator>(this);
- return condExpr->getCond()->isConstantExpr(isIntConst) &&
- condExpr->getLHS()->isConstantExpr(isIntConst) &&
- condExpr->getRHS()->isConstantExpr(isIntConst);
- default:
+ return condExpr->getCond()->isConstantExpr(isIntConst, loc) &&
+ condExpr->getLHS()->isConstantExpr(isIntConst, loc) &&
+ condExpr->getRHS()->isConstantExpr(isIntConst, loc);
+ default:
+ loc = getLocStart();
return false;
}
}
Modified: cfe/cfe/trunk/AST/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaDecl.cpp?rev=39454&r1=39453&r2=39454&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/AST/SemaDecl.cpp Wed Jul 11 11:44:36 2007
@@ -31,12 +31,14 @@
// a constant expression of type int with a value greater than zero.
bool Sema::isConstantArrayType(ArrayType *ary, SourceLocation loc) {
if (Expr *size = ary->getSize()) {
- if (!size->isConstantExpr()) {
- Diag(loc, diag::err_typecheck_illegal_vla);
+ SourceLocation expLoc;
+ if (!size->isConstantExpr(expLoc)) {
+ Diag(expLoc, diag::err_typecheck_illegal_vla);
return false;
}
if (!size->getType()->isIntegerType()) {
- Diag(loc, diag::err_array_size_non_int, size->getType().getAsString());
+ Diag(size->getLocStart(), diag::err_array_size_non_int,
+ size->getType().getAsString());
return false;
}
// We have a constant expression with an integer type, now make sure
@@ -778,9 +780,10 @@
return 0;
}
}
+ SourceLocation expLoc;
// C99 6.7.2.2p2: Make sure we have an integer constant expression.
- if (Val && !((Expr *)Val)->isIntegerConstantExpr()) {
- Diag(IdLoc, diag::err_enum_value_not_integer_constant_expr, Id->getName());
+ if (Val && !((Expr *)Val)->isIntegerConstantExpr(expLoc)) {
+ Diag(expLoc, diag::err_enum_value_not_integer_constant_expr, Id->getName());
return 0;
}
QualType Ty = Context.getTagDeclType(TheEnumDecl);
Modified: cfe/cfe/trunk/AST/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaStmt.cpp?rev=39454&r1=39453&r2=39454&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/SemaStmt.cpp (original)
+++ cfe/cfe/trunk/AST/SemaStmt.cpp Wed Jul 11 11:44:36 2007
@@ -37,8 +37,9 @@
SourceLocation ColonLoc, StmtTy *SubStmt) {
assert((LHSVal != 0) && "missing expression in case statement");
+ SourceLocation expLoc;
// C99 6.8.4.2p3: The expression shall be an integer constant.
- if (!((Expr *)LHSVal)->isIntegerConstantExpr())
+ if (!((Expr *)LHSVal)->isIntegerConstantExpr(expLoc))
return Diag(CaseLoc, diag::err_case_label_not_integer_constant_expr);
return new CaseStmt((Expr*)LHSVal, (Expr*)RHSVal, (Stmt*)SubStmt);
Modified: cfe/cfe/trunk/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Type.cpp?rev=39454&r1=39453&r2=39454&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/Type.cpp (original)
+++ cfe/cfe/trunk/AST/Type.cpp Wed Jul 11 11:44:36 2007
@@ -278,10 +278,10 @@
// The only variable size types are auto arrays within a function. Structures
// cannot contain a VLA member. They can have a flexible array member, however
// the structure is still constant size (C99 6.7.2.1p16).
-bool Type::isConstantSizeType() const {
+bool Type::isConstantSizeType(SourceLocation &loc) const {
if (const ArrayType *ary = dyn_cast<ArrayType>(CanonicalType)) {
if (Expr *size = ary->getSize()) {
- if (!size->isConstantExpr())
+ if (!size->isConstantExpr(loc))
return false; // Variable Length Array
}
}
Modified: cfe/cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaDecl.cpp?rev=39454&r1=39453&r2=39454&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaDecl.cpp Wed Jul 11 11:44:36 2007
@@ -31,12 +31,14 @@
// a constant expression of type int with a value greater than zero.
bool Sema::isConstantArrayType(ArrayType *ary, SourceLocation loc) {
if (Expr *size = ary->getSize()) {
- if (!size->isConstantExpr()) {
- Diag(loc, diag::err_typecheck_illegal_vla);
+ SourceLocation expLoc;
+ if (!size->isConstantExpr(expLoc)) {
+ Diag(expLoc, diag::err_typecheck_illegal_vla);
return false;
}
if (!size->getType()->isIntegerType()) {
- Diag(loc, diag::err_array_size_non_int, size->getType().getAsString());
+ Diag(size->getLocStart(), diag::err_array_size_non_int,
+ size->getType().getAsString());
return false;
}
// We have a constant expression with an integer type, now make sure
@@ -778,9 +780,10 @@
return 0;
}
}
+ SourceLocation expLoc;
// C99 6.7.2.2p2: Make sure we have an integer constant expression.
- if (Val && !((Expr *)Val)->isIntegerConstantExpr()) {
- Diag(IdLoc, diag::err_enum_value_not_integer_constant_expr, Id->getName());
+ if (Val && !((Expr *)Val)->isIntegerConstantExpr(expLoc)) {
+ Diag(expLoc, diag::err_enum_value_not_integer_constant_expr, Id->getName());
return 0;
}
QualType Ty = Context.getTagDeclType(TheEnumDecl);
Modified: cfe/cfe/trunk/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaStmt.cpp?rev=39454&r1=39453&r2=39454&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/SemaStmt.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaStmt.cpp Wed Jul 11 11:44:36 2007
@@ -37,8 +37,9 @@
SourceLocation ColonLoc, StmtTy *SubStmt) {
assert((LHSVal != 0) && "missing expression in case statement");
+ SourceLocation expLoc;
// C99 6.8.4.2p3: The expression shall be an integer constant.
- if (!((Expr *)LHSVal)->isIntegerConstantExpr())
+ if (!((Expr *)LHSVal)->isIntegerConstantExpr(expLoc))
return Diag(CaseLoc, diag::err_case_label_not_integer_constant_expr);
return new CaseStmt((Expr*)LHSVal, (Expr*)RHSVal, (Stmt*)SubStmt);
Modified: cfe/cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/Expr.h?rev=39454&r1=39453&r2=39454&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Expr.h Wed Jul 11 11:44:36 2007
@@ -63,8 +63,10 @@
bool isNullPointerConstant() const;
- bool isConstantExpr() const { return isConstantExpr(false); }
- bool isIntegerConstantExpr() const { return isConstantExpr(true); }
+ bool isConstantExpr(SourceLocation &loc) const
+ { return isConstantExpr(false, loc); }
+ bool isIntegerConstantExpr(SourceLocation &loc) const
+ { return isConstantExpr(true, loc); }
virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) {
@@ -73,7 +75,7 @@
}
static bool classof(const Expr *) { return true; }
private:
- bool isConstantExpr(bool isIntegerConstant) const;
+ bool isConstantExpr(bool isIntegerConstant, SourceLocation &loc) const;
};
//===----------------------------------------------------------------------===//
@@ -232,9 +234,9 @@
Expr *getSubExpr() const { return Val; }
virtual SourceRange getSourceRange() const {
if (isPostfix())
- return SourceRange(getSubExpr()->getLocStart(), Loc);
+ return SourceRange(Val->getLocStart(), Loc);
else
- return SourceRange(Loc, getSubExpr()->getLocEnd());
+ return SourceRange(Loc, Val->getLocEnd());
}
bool isPostfix() const { return isPostfix(Opc); }
bool isIncrementDecrementOp() const { return Opc>=PostInc && Opc<=PreDec; }
Modified: cfe/cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/Type.h?rev=39454&r1=39453&r2=39454&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Type.h Wed Jul 11 11:44:36 2007
@@ -26,6 +26,7 @@
class RecordDecl;
class EnumDecl;
class Expr;
+ class SourceLocation;
/// QualType - For efficiency, we don't store CVR-qualified types as nodes on
/// their own: instead each reference to a type stores the qualifiers. This
@@ -233,7 +234,7 @@
bool isSignedIntegerType() const; // C99 6.2.5p4
bool isUnsignedIntegerType() const; // C99 6.2.5p6
- bool isConstantSizeType() const; // C99 6.7.5p3: VLA if false
+ bool isConstantSizeType(SourceLocation &) const; // C99 6.7.5p3: VLA if false
/// Compatibility predicates used to check assignment expressions.
static bool typesAreCompatible(QualType, QualType); // C99 6.2.7p1
More information about the cfe-commits
mailing list