[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