[cfe-commits] r41672 - in /cfe/trunk: Sema/Sema.h Sema/SemaDecl.cpp include/clang/Basic/DiagnosticKinds.def test/Sema/array-init.c
Steve Naroff
snaroff at apple.com
Sun Sep 2 08:34:31 PDT 2007
Author: snaroff
Date: Sun Sep 2 10:34:30 2007
New Revision: 41672
URL: http://llvm.org/viewvc/llvm-project?rev=41672&view=rev
Log:
More semantic analysis of initializers.
Added 2 errors and one warning, updated test case.
Modified:
cfe/trunk/Sema/Sema.h
cfe/trunk/Sema/SemaDecl.cpp
cfe/trunk/include/clang/Basic/DiagnosticKinds.def
cfe/trunk/test/Sema/array-init.c
Modified: cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.h?rev=41672&r1=41671&r2=41672&view=diff
==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Sun Sep 2 10:34:30 2007
@@ -30,6 +30,7 @@
class Preprocessor;
class Decl;
class Expr;
+ class InitListExpr;
class VarDecl;
class ParmVarDecl;
class TypedefDecl;
@@ -441,8 +442,10 @@
IdentifierInfo &Comp, SourceLocation CmpLoc);
/// type checking declaration initializers (C99 6.7.8)
- QualType CheckInitializer(Expr *simpleInit_or_initList, QualType declType);
+ QualType CheckInitializer(Expr *simpleInit_or_initList, QualType declType,
+ bool isStatic);
bool CheckSingleInitializer(Expr *simpleInit, QualType declType);
+ bool RequireConstantExprs(InitListExpr *IList);
/// ConvertIntegerToTypeWarnOnOverflow - Convert the specified APInt to have
/// the specified width and sign. If an overflow occurs, detect it and emit
Modified: cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaDecl.cpp?rev=41672&r1=41671&r2=41672&view=diff
==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Sun Sep 2 10:34:30 2007
@@ -253,6 +253,10 @@
case Compatible:
break;
case Incompatible:
+ // FIXME: tighten up this check which should allow:
+ // char s[] = "abc", which is identical to char s[] = { 'a', 'b', 'c' };
+ if (rhsType == Context.getPointerType(Context.CharTy))
+ break;
Diag(loc, diag::err_typecheck_assign_incompatible,
DeclType.getAsString(), rhsType.getAsString(),
Init->getSourceRange());
@@ -285,13 +289,36 @@
return false;
}
-QualType Sema::CheckInitializer(Expr *Init, QualType DeclType) {
+bool Sema::RequireConstantExprs(InitListExpr *IList) {
+ bool hadError = false;
+ for (unsigned i = 0; i < IList->getNumInits(); i++) {
+ Expr *expr = IList->getInit(i);
+
+ if (InitListExpr *InitList = dyn_cast<InitListExpr>(expr))
+ RequireConstantExprs(InitList);
+ else {
+ SourceLocation loc;
+ // FIXME: should be isConstantExpr()...
+ if (!expr->isIntegerConstantExpr(Context, &loc)) {
+ Diag(loc, diag::err_init_element_not_constant, expr->getSourceRange());
+ hadError = true;
+ }
+ }
+ }
+ return hadError;
+}
+
+QualType Sema::CheckInitializer(Expr *Init, QualType DeclType, bool isStatic) {
InitListExpr *InitList = dyn_cast<InitListExpr>(Init);
if (!InitList) {
return CheckSingleInitializer(Init, DeclType) ? QualType() : DeclType;
}
// We have an InitListExpr, make sure we set the type.
Init->setType(DeclType);
+
+ if (isStatic) // C99 6.7.8p4.
+ RequireConstantExprs(InitList);
+
// FIXME: Lot of checking still to do...
return DeclType;
}
@@ -395,6 +422,11 @@
case DeclSpec::SCS_register: SC = VarDecl::Register; break;
}
if (S->getParent() == 0) {
+ if (Init) {
+ if (SC == VarDecl::Extern)
+ Diag(D.getIdentifierLoc(), diag::warn_extern_init);
+ CheckInitializer(Init, R, true);
+ }
// File scope. C99 6.9.2p2: A declaration of an identifier for and
// object that has file scope without an initializer, and without a
// storage-class specifier or with the storage-class specifier "static",
@@ -434,7 +466,12 @@
NewVD = new FileVarDecl(D.getIdentifierLoc(), II, R, SC, LastDeclarator);
} else {
if (Init) {
- CheckInitializer(Init, R);
+ if (SC == VarDecl::Extern) { // C99 6.7.8p5
+ Diag(D.getIdentifierLoc(), diag::err_block_extern_cant_init);
+ InvalidDecl = true;
+ } else {
+ CheckInitializer(Init, R, SC == VarDecl::Static);
+ }
}
// Block scope. C99 6.7p7: If an identifier for an object is declared with
// no linkage (C99 6.2.2p6), the type for the object shall be complete...
Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=41672&r1=41671&r2=41672&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Sun Sep 2 10:34:30 2007
@@ -542,6 +542,12 @@
"zero size arrays are an extension")
DIAG(err_array_size_non_int, ERROR,
"size of array has non-integer type '%0'")
+DIAG(err_init_element_not_constant, ERROR,
+ "initializer element is not constant")
+DIAG(err_block_extern_cant_init, ERROR,
+ "'extern' variable cannot have an initializer")
+DIAG(warn_extern_init, WARNING,
+ "'extern' variable has an initializer")
DIAG(err_redefinition_of_label, ERROR,
"redefinition of label '%0'")
Modified: cfe/trunk/test/Sema/array-init.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/array-init.c?rev=41672&r1=41671&r2=41672&view=diff
==============================================================================
--- cfe/trunk/test/Sema/array-init.c (original)
+++ cfe/trunk/test/Sema/array-init.c Sun Sep 2 10:34:30 2007
@@ -1,5 +1,12 @@
// RUN: clang -parse-ast-check -pedantic %s
+static int x, y, z;
+
+static int ary[] = { x, y, z }; // expected-error{{initializer element is not constant}}
+int ary2[] = { x, y, z }; // expected-error{{initializer element is not constant}}
+
+extern int fileScopeExtern[3] = { 1, 3, 5 }; // expected-warning{{'extern' variable has an initializer}}
+
void func() {
int x = 1;
@@ -24,4 +31,6 @@
} z = { 1 };
struct threeElements *p = 7; // expected-warning{{incompatible types assigning 'int' to 'struct threeElements *'}}
+
+ extern int blockScopeExtern[3] = { 1, 3, 5 }; // expected-error{{'extern' variable cannot have an initializer}}
}
More information about the cfe-commits
mailing list