[cfe-commits] r69943 - in /cfe/trunk: clang.xcodeproj/project.pbxproj include/clang/Basic/DiagnosticSemaKinds.td lib/AST/Type.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaType.cpp test/SemaObjC/sizeof-interface.m

Chris Lattner sabre at nondot.org
Thu Apr 23 17:30:49 PDT 2009


Author: lattner
Date: Thu Apr 23 19:30:45 2009
New Revision: 69943

URL: http://llvm.org/viewvc/llvm-project?rev=69943&view=rev
Log:
Fix rdar://6821047 - clang crashes on subscript of interface in 64-bit mode

Several changes here:
1. We change Type::isIncompleteType to realize that forward declared 
   interfaces are incomplete.  This eliminate special case code for this
   from the sizeof path, and starts us rejecting P[4] when P is a pointer
   to an incomplete interface.
2. Explicitly reject P[4] when P points to an interface in non-fragile ABI
   mode.
3. Switch the sizeof(interface) diagnostic back to an error instead of a 
   warning in non-fragile abi mode.



Modified:
    cfe/trunk/clang.xcodeproj/project.pbxproj
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/AST/Type.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaType.cpp
    cfe/trunk/test/SemaObjC/sizeof-interface.m

Modified: cfe/trunk/clang.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/clang.xcodeproj/project.pbxproj?rev=69943&r1=69942&r2=69943&view=diff

==============================================================================
--- cfe/trunk/clang.xcodeproj/project.pbxproj (original)
+++ cfe/trunk/clang.xcodeproj/project.pbxproj Thu Apr 23 19:30:45 2009
@@ -690,6 +690,8 @@
 		DEF168620F9549250098507F /* FixItRewriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FixItRewriter.h; path = clang/Frontend/FixItRewriter.h; sourceTree = "<group>"; };
 		DEF169220F9645960098507F /* FrontendDiagnostic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FrontendDiagnostic.h; path = clang/Frontend/FrontendDiagnostic.h; sourceTree = "<group>"; };
 		DEF1692C0F9645BF0098507F /* AnalysisDiagnostic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AnalysisDiagnostic.h; path = clang/Analysis/AnalysisDiagnostic.h; sourceTree = "<group>"; };
+		DEF16BE40FA13A5B0098507F /* TypeNodes.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = TypeNodes.def; path = clang/AST/TypeNodes.def; sourceTree = "<group>"; };
+		DEF16BE50FA13A650098507F /* TypeOrdering.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TypeOrdering.h; path = clang/AST/TypeOrdering.h; sourceTree = "<group>"; };
 		DEF2E95E0C5FBD74000C4259 /* InternalsManual.html */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.html; name = InternalsManual.html; path = docs/InternalsManual.html; sourceTree = "<group>"; };
 		DEF2EDA60C6A4252000C4259 /* StmtDumper.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = StmtDumper.cpp; path = lib/AST/StmtDumper.cpp; sourceTree = "<group>"; tabWidth = 2; };
 		DEF2EFF20C6CDD74000C4259 /* CGExprAgg.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGExprAgg.cpp; path = lib/CodeGen/CGExprAgg.cpp; sourceTree = "<group>"; tabWidth = 2; };
@@ -1132,6 +1134,8 @@
 				35CFFE010CA1CBDD00E6F2BE /* StmtGraphTraits.h */,
 				1A68BC120D0CADDD001A28C8 /* TargetBuiltins.h */,
 				DEDFF87F0F848CE30035BD10 /* TemplateName.h */,
+				DEF16BE40FA13A5B0098507F /* TypeNodes.def */,
+				DEF16BE50FA13A650098507F /* TypeOrdering.h */,
 				DE3464210B03040900DBC861 /* Type.h */,
 			);
 			name = AST;
@@ -1189,9 +1193,6 @@
 		DED7D7300A524295003AD0FB /* Basic */ = {
 			isa = PBXGroup;
 			children = (
-				9063F2280F9E911F002F7251 /* OnDiskHashTable.h */,
-				9063F2290F9E911F002F7251 /* SourceManagerInternals.h */,
-				9063F22A0F9E911F002F7251 /* TemplateKinds.h */,
 				906BF4AE0F83BA16001071FA /* ConvertUTF.h */,
 				DED7D7310A524295003AD0FB /* Diagnostic.h */,
 				DEDFFF070F959EE60035BD10 /* Diagnostic.td */,
@@ -1207,12 +1208,15 @@
 				DED7D7330A524295003AD0FB /* FileManager.h */,
 				DE3986EF0CB8D4B300223765 /* IdentifierTable.h */,
 				DE06B73D0A8307640050E87E /* LangOptions.h */,
+				9063F2280F9E911F002F7251 /* OnDiskHashTable.h */,
 				DE8824560ED1244600CBC30A /* OperatorKinds.def */,
 				DE8824530ED1243E00CBC30A /* OperatorKinds.h */,
 				DEAABDF70F5F477C0098928A /* PrettyStackTrace.h */,
 				DED7D7350A524295003AD0FB /* SourceLocation.h */,
 				DED7D7360A524295003AD0FB /* SourceManager.h */,
+				9063F2290F9E911F002F7251 /* SourceManagerInternals.h */,
 				DE46BF270AE0A82D00CC047C /* TargetInfo.h */,
+				9063F22A0F9E911F002F7251 /* TemplateKinds.h */,
 				DED7D7370A524295003AD0FB /* TokenKinds.def */,
 				DED7D7380A524295003AD0FB /* TokenKinds.h */,
 				DEB089EE0F12F1D900522C07 /* TypeTraits.h */,

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=69943&r1=69942&r2=69943&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Apr 23 19:30:45 2009
@@ -917,10 +917,7 @@
   "invalid application of 'sizeof' to a function type">;
 def ext_sizeof_void_type : Extension<
   "invalid application of '%0' to a void type">;
-def err_sizeof_forward_interface : Error<
-  "invalid application of '%select{alignof|sizeof}1' to a forward declared"
-  " interface %0">;
-def err_sizeof_nonfragile_interface : Warning<
+def err_sizeof_nonfragile_interface : Error<
   "invalid application of '%select{alignof|sizeof}1' to interface %0 in "
   "non-fragile ABI">;
 def err_atdef_nonfragile_interface : Error<
@@ -948,6 +945,9 @@
   "subscript of pointer to function type %0">;
 def err_subscript_incomplete_type : Error<
   "subscript of pointer to incomplete type %0">;
+def err_subscript_nonfragile_interface : Error<
+  "subscript requires size of interface %0, which is not constant in "
+  "non-fragile ABI">;
 def err_typecheck_member_reference_struct_union : Error<
   "member reference base type %0 is not a structure or union">;
 def err_typecheck_member_reference_ivar : Error<

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=69943&r1=69942&r2=69943&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Thu Apr 23 19:30:45 2009
@@ -825,6 +825,10 @@
   case IncompleteArray:
     // An array of unknown size is an incomplete type (C99 6.2.5p22).
     return true;
+  case ObjCInterface:
+  case ObjCQualifiedInterface:
+    // ObjC interfaces are incomplete if they are @class, not @interface.
+    return cast<ObjCInterfaceType>(this)->getDecl()->isForwardDecl();
   }
 }
 

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=69943&r1=69942&r2=69943&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Apr 23 19:30:45 2009
@@ -1231,37 +1231,33 @@
 
   // C99 6.5.3.4p1:
   if (isa<FunctionType>(exprType)) {
-    // alignof(function) is allowed.
+    // alignof(function) is allowed as an extension.
     if (isSizeof)
       Diag(OpLoc, diag::ext_sizeof_function_type) << ExprRange;
     return false;
   }
   
+  // Allow sizeof(void)/alignof(void) as an extension.
   if (exprType->isVoidType()) {
     Diag(OpLoc, diag::ext_sizeof_void_type)
       << (isSizeof ? "sizeof" : "__alignof") << ExprRange;
     return false;
   }
   
-  // sizeof(interface) and sizeof(interface<proto>)
-  if (const ObjCInterfaceType *IIT = exprType->getAsObjCInterfaceType()) {
-    if (IIT->getDecl()->isForwardDecl()) {
-      Diag(OpLoc, diag::err_sizeof_forward_interface)
-        << IIT->getDecl()->getDeclName() << isSizeof;
-      return true;
-    }
-
-    if (LangOpts.ObjCNonFragileABI) {
-      Diag(OpLoc, diag::err_sizeof_nonfragile_interface)
-        << IIT->getDecl()->getDeclName() << isSizeof;
-      //return false;
-    }
+  if (RequireCompleteType(OpLoc, exprType,
+                          isSizeof ? diag::err_sizeof_incomplete_type : 
+                          diag::err_alignof_incomplete_type,
+                          ExprRange))
+    return true;
+  
+  // Reject sizeof(interface) and sizeof(interface<proto>) in 64-bit mode.
+  if (exprType->isObjCInterfaceType() && LangOpts.ObjCNonFragileABI) {
+    Diag(OpLoc, diag::err_sizeof_nonfragile_interface)
+      << exprType << isSizeof;
+    return true;
   }
     
-  return RequireCompleteType(OpLoc, exprType,
-                                isSizeof ? diag::err_sizeof_incomplete_type : 
-                                           diag::err_alignof_incomplete_type,
-                                ExprRange);
+  return false;
 }
 
 bool Sema::CheckAlignOfExpr(Expr *E, SourceLocation OpLoc,
@@ -1651,12 +1647,19 @@
       << ResultType << BaseExpr->getSourceRange();
     return ExprError();
   }
+  
   if (!ResultType->isDependentType() &&
-      RequireCompleteType(BaseExpr->getLocStart(), ResultType, 
-                          diag::err_subscript_incomplete_type,
+      RequireCompleteType(LLoc, ResultType, diag::err_subscript_incomplete_type,
                           BaseExpr->getSourceRange()))
     return ExprError();
-
+  
+  // Diagnose bad cases where we step over interface counts.
+  if (ResultType->isObjCInterfaceType() && LangOpts.ObjCNonFragileABI) {
+    Diag(LLoc, diag::err_subscript_nonfragile_interface)
+      << ResultType << BaseExpr->getSourceRange();
+    return ExprError();
+  }
+  
   Base.release();
   Idx.release();
   return Owned(new (Context) ArraySubscriptExpr(LHSExp, RHSExp,

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=69943&r1=69942&r2=69943&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Thu Apr 23 19:30:45 2009
@@ -1060,8 +1060,8 @@
 /// @returns @c true if @p T is incomplete and a diagnostic was emitted,
 /// @c false otherwise.
 bool Sema::RequireCompleteType(SourceLocation Loc, QualType T, unsigned diag,
-                                  SourceRange Range1, SourceRange Range2,
-                                  QualType PrintType) {
+                               SourceRange Range1, SourceRange Range2,
+                               QualType PrintType) {
   // If we have a complete type, we're done.
   if (!T->isIncompleteType())
     return false;

Modified: cfe/trunk/test/SemaObjC/sizeof-interface.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/sizeof-interface.m?rev=69943&r1=69942&r2=69943&view=diff

==============================================================================
--- cfe/trunk/test/SemaObjC/sizeof-interface.m (original)
+++ cfe/trunk/test/SemaObjC/sizeof-interface.m Thu Apr 23 19:30:45 2009
@@ -3,9 +3,17 @@
 @class I0;
 
 // rdar://6811884
-int g0 = sizeof(I0); // expected-error{{invalid application of 'sizeof' to a forward declared interface 'I0'}}
+int g0 = sizeof(I0); // expected-error{{invalid application of 'sizeof' to an incomplete type 'I0'}}
+
+// rdar://6821047
+void *g3(I0 *P) {
+  return &P[4];   // expected-error{{subscript of pointer to incomplete type 'I0'}}
+}
+
+
 
 @interface I0 {
+ at public
   char x[4];
 }
 
@@ -13,7 +21,7 @@
 @end
 
 // size == 4
-int g1[ sizeof(I0)     // expected-warning {{invalid application of 'sizeof' to interface 'I0' in non-fragile ABI}}
+int g1[ sizeof(I0)     // expected-error {{invalid application of 'sizeof' to interface 'I0' in non-fragile ABI}}
        == 4 ? 1 : -1];
 
 @implementation I0
@@ -22,7 +30,7 @@
 
 // size == 4 (we do not include extended properties in the
 // sizeof).
-int g2[ sizeof(I0)   // expected-warning {{invalid application of 'sizeof' to interface 'I0' in non-fragile ABI}}
+int g2[ sizeof(I0)   // expected-error {{invalid application of 'sizeof' to interface 'I0' in non-fragile ABI}}
        == 4 ? 1 : -1];
 
 @interface I1
@@ -38,3 +46,9 @@
 // FIXME: This is currently broken due to the way the record layout we
 // create is tied to whether we have seen synthesized properties. Ugh.
 // int g3[ sizeof(I1) == 0 ? 1 : -1];
+
+// rdar://6821047
+int bar(I0 *P) {
+  return P[4].x[2];  // expected-error {{subscript requires size of interface 'I0', which is not constant in non-fragile ABI}}
+}
+





More information about the cfe-commits mailing list