[cfe-commits] r39371 - in /cfe/cfe/trunk: AST/SemaDecl.cpp AST/SemaExpr.cpp Sema/SemaDecl.cpp Sema/SemaExpr.cpp include/clang/Basic/DiagnosticKinds.def
Steve Naroff
snaroff at apple.com
Wed Jul 11 09:43:42 PDT 2007
Author: snaroff
Date: Wed Jul 11 11:43:42 2007
New Revision: 39371
URL: http://llvm.org/viewvc/llvm-project?rev=39371&view=rev
Log:
Bug #:
Submitted by:
Reviewed by:
- ParseMemberReferenceExpr wasn't operating on the canonical type. From
now on, I will make sure the prologue to each Parse/Check function has
both the qualified type and the canonical type.
- More refinements to ParseDeclarator. It was allowing variable declarations
to incomplete types (e.g. void, struct foo, where foo wasn't defined).
Modified:
cfe/cfe/trunk/AST/SemaDecl.cpp
cfe/cfe/trunk/AST/SemaExpr.cpp
cfe/cfe/trunk/Sema/SemaDecl.cpp
cfe/cfe/trunk/Sema/SemaExpr.cpp
cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
Modified: cfe/cfe/trunk/AST/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaDecl.cpp?rev=39371&r1=39370&r2=39371&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/AST/SemaDecl.cpp Wed Jul 11 11:43:42 2007
@@ -260,17 +260,28 @@
TypeRef R = GetTypeForDeclarator(D, S);
if (R.isNull()) return 0;
- ObjectDecl::StorageClass S;
+ ObjectDecl::StorageClass SC;
switch (D.getDeclSpec().getStorageClassSpec()) {
default: assert(0 && "Unknown storage class!");
- case 0: S = ObjectDecl::None;
- case DeclSpec::SCS_extern: S = ObjectDecl::Extern; break;
- case DeclSpec::SCS_static: S = ObjectDecl::Static; break;
+ case DeclSpec::SCS_unspecified: SC = ObjectDecl::None; break;
+ case DeclSpec::SCS_extern: SC = ObjectDecl::Extern; break;
+ case DeclSpec::SCS_static: SC = ObjectDecl::Static; break;
// The following 2 should never be seen in this context.
- case DeclSpec::SCS_auto: S = ObjectDecl::Auto; break;
- case DeclSpec::SCS_register: S = ObjectDecl::Register; break;
+ case DeclSpec::SCS_auto: SC = ObjectDecl::Auto; break;
+ case DeclSpec::SCS_register: SC = ObjectDecl::Register; break;
}
- VarDecl *NewVD = new VarDecl(D.getIdentifierLoc(), II, R, S);
+ // C99 6.9.2p3: If the declaration of an identifier for an object is a
+ // tentative definition and has internal linkage, the declared type shall
+ // not be an incomplete type.
+ if ((S->getParent() == 0 && !Init && SC == ObjectDecl::None) ||
+ SC == ObjectDecl::Static) {
+ // FIXME: need a check for internal linkage.
+ if (R->isIncompleteType()) {
+ Diag(D.getIdentifierLoc(), diag::err_typecheck_decl_incomplete_type, R);
+ return 0;
+ }
+ }
+ VarDecl *NewVD = new VarDecl(D.getIdentifierLoc(), II, R, SC);
// Merge the decl with the existing one if appropriate.
if (PrevDecl) {
Modified: cfe/cfe/trunk/AST/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaExpr.cpp?rev=39371&r1=39370&r2=39371&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/AST/SemaExpr.cpp Wed Jul 11 11:43:42 2007
@@ -266,20 +266,24 @@
ParseMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc,
tok::TokenKind OpKind, SourceLocation MemberLoc,
IdentifierInfo &Member) {
- TypeRef BT = ((Expr *)Base)->getTypeRef();
-
- assert(!BT.isNull() && "no type for member expression");
+ TypeRef qualifiedType = ((Expr *)Base)->getTypeRef();
+
+ assert(!qualifiedType.isNull() && "no type for member expression");
+
+ Type *canonType = qualifiedType->getCanonicalType();
if (OpKind == tok::arrow) {
- if (PointerType *PT = dyn_cast<PointerType>(BT))
- BT = PT->getPointeeType();
- else
+ if (PointerType *PT = dyn_cast<PointerType>(canonType)) {
+ qualifiedType = PT->getPointeeType();
+ canonType = qualifiedType->getCanonicalType();
+ } else
return Diag(OpLoc, diag::err_typecheck_member_reference_arrow);
}
- if (isa<RecordType>(BT)) { // get the struct/union definition from the type.
- RecordDecl *RD = cast<RecordType>(BT)->getDecl();
+ if (isa<RecordType>(canonType)) {
+ // get the struct/union definition from the type.
+ RecordDecl *RD = cast<RecordType>(canonType)->getDecl();
- if (BT->isIncompleteType())
+ if (canonType->isIncompleteType())
return Diag(OpLoc, diag::err_typecheck_incomplete_tag, RD->getName());
if (FieldDecl *MemberDecl = RD->getMember(&Member))
Modified: cfe/cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaDecl.cpp?rev=39371&r1=39370&r2=39371&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaDecl.cpp Wed Jul 11 11:43:42 2007
@@ -260,17 +260,28 @@
TypeRef R = GetTypeForDeclarator(D, S);
if (R.isNull()) return 0;
- ObjectDecl::StorageClass S;
+ ObjectDecl::StorageClass SC;
switch (D.getDeclSpec().getStorageClassSpec()) {
default: assert(0 && "Unknown storage class!");
- case 0: S = ObjectDecl::None;
- case DeclSpec::SCS_extern: S = ObjectDecl::Extern; break;
- case DeclSpec::SCS_static: S = ObjectDecl::Static; break;
+ case DeclSpec::SCS_unspecified: SC = ObjectDecl::None; break;
+ case DeclSpec::SCS_extern: SC = ObjectDecl::Extern; break;
+ case DeclSpec::SCS_static: SC = ObjectDecl::Static; break;
// The following 2 should never be seen in this context.
- case DeclSpec::SCS_auto: S = ObjectDecl::Auto; break;
- case DeclSpec::SCS_register: S = ObjectDecl::Register; break;
+ case DeclSpec::SCS_auto: SC = ObjectDecl::Auto; break;
+ case DeclSpec::SCS_register: SC = ObjectDecl::Register; break;
}
- VarDecl *NewVD = new VarDecl(D.getIdentifierLoc(), II, R, S);
+ // C99 6.9.2p3: If the declaration of an identifier for an object is a
+ // tentative definition and has internal linkage, the declared type shall
+ // not be an incomplete type.
+ if ((S->getParent() == 0 && !Init && SC == ObjectDecl::None) ||
+ SC == ObjectDecl::Static) {
+ // FIXME: need a check for internal linkage.
+ if (R->isIncompleteType()) {
+ Diag(D.getIdentifierLoc(), diag::err_typecheck_decl_incomplete_type, R);
+ return 0;
+ }
+ }
+ VarDecl *NewVD = new VarDecl(D.getIdentifierLoc(), II, R, SC);
// Merge the decl with the existing one if appropriate.
if (PrevDecl) {
Modified: cfe/cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaExpr.cpp?rev=39371&r1=39370&r2=39371&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaExpr.cpp Wed Jul 11 11:43:42 2007
@@ -266,20 +266,24 @@
ParseMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc,
tok::TokenKind OpKind, SourceLocation MemberLoc,
IdentifierInfo &Member) {
- TypeRef BT = ((Expr *)Base)->getTypeRef();
-
- assert(!BT.isNull() && "no type for member expression");
+ TypeRef qualifiedType = ((Expr *)Base)->getTypeRef();
+
+ assert(!qualifiedType.isNull() && "no type for member expression");
+
+ Type *canonType = qualifiedType->getCanonicalType();
if (OpKind == tok::arrow) {
- if (PointerType *PT = dyn_cast<PointerType>(BT))
- BT = PT->getPointeeType();
- else
+ if (PointerType *PT = dyn_cast<PointerType>(canonType)) {
+ qualifiedType = PT->getPointeeType();
+ canonType = qualifiedType->getCanonicalType();
+ } else
return Diag(OpLoc, diag::err_typecheck_member_reference_arrow);
}
- if (isa<RecordType>(BT)) { // get the struct/union definition from the type.
- RecordDecl *RD = cast<RecordType>(BT)->getDecl();
+ if (isa<RecordType>(canonType)) {
+ // get the struct/union definition from the type.
+ RecordDecl *RD = cast<RecordType>(canonType)->getDecl();
- if (BT->isIncompleteType())
+ if (canonType->isIncompleteType())
return Diag(OpLoc, diag::err_typecheck_incomplete_tag, RD->getName());
if (FieldDecl *MemberDecl = RD->getMember(&Member))
Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=39371&r1=39370&r2=39371&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:43:42 2007
@@ -504,6 +504,8 @@
"cannot modify read-only value of type '%s'")
DIAG(err_typecheck_arithmetic_incomplete_type, ERROR,
"arithmetic on pointer to incomplete type '%s'")
+DIAG(err_typecheck_decl_incomplete_type, ERROR,
+ "variable has incomplete type '%s'")
// Statements.
DIAG(err_continue_not_in_loop, ERROR,
More information about the cfe-commits
mailing list