[cfe-commits] r170081 - in /cfe/trunk: include/clang/AST/CanonicalType.h lib/Rewrite/Frontend/RewriteModernObjC.cpp lib/Sema/SemaDecl.cpp test/SemaCXX/array-bound-merge.cpp test/SemaTemplate/instantiate-init.cpp

Eli Friedman eli.friedman at gmail.com
Wed Dec 12 17:43:21 PST 2012


Author: efriedma
Date: Wed Dec 12 19:43:21 2012
New Revision: 170081

URL: http://llvm.org/viewvc/llvm-project?rev=170081&view=rev
Log:
Using CanQualType::getAs<ArrayType> is unsafe; fix the code currently using it,
and make sure additional uses don't get introduced.  <rdar://problem/12858424>.


Modified:
    cfe/trunk/include/clang/AST/CanonicalType.h
    cfe/trunk/lib/Rewrite/Frontend/RewriteModernObjC.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/SemaCXX/array-bound-merge.cpp
    cfe/trunk/test/SemaTemplate/instantiate-init.cpp

Modified: cfe/trunk/include/clang/AST/CanonicalType.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/CanonicalType.h?rev=170081&r1=170080&r2=170081&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/CanonicalType.h (original)
+++ cfe/trunk/include/clang/AST/CanonicalType.h Wed Dec 12 19:43:21 2012
@@ -514,55 +514,13 @@
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Type *, getClass)
 };
 
-template<>
-struct CanProxyAdaptor<ArrayType> : public CanProxyBase<ArrayType> {
-  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
-  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
-                                      getSizeModifier)
-  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
-};
-
-template<>
-struct CanProxyAdaptor<ConstantArrayType>
-  : public CanProxyBase<ConstantArrayType> {
-  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
-  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
-                                      getSizeModifier)
-  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
-  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const llvm::APInt &, getSize)
-};
-
-template<>
-struct CanProxyAdaptor<IncompleteArrayType>
-  : public CanProxyBase<IncompleteArrayType> {
-  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
-  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
-                                      getSizeModifier)
-  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
-};
-
-template<>
-struct CanProxyAdaptor<VariableArrayType>
-  : public CanProxyBase<VariableArrayType> {
-  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
-  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
-                                      getSizeModifier)
-  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
-  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getSizeExpr)
-  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceRange, getBracketsRange)
-  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getLBracketLoc)
-  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getRBracketLoc)
-};
-
-template<>
-struct CanProxyAdaptor<DependentSizedArrayType>
-  : public CanProxyBase<DependentSizedArrayType> {
-  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
-  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getSizeExpr)
-  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceRange, getBracketsRange)
-  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getLBracketLoc)
-  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getRBracketLoc)
-};
+// CanProxyAdaptors for arrays are intentionally unimplemented because
+// they are not safe.
+template<> struct CanProxyAdaptor<ArrayType>;
+template<> struct CanProxyAdaptor<ConstantArrayType>;
+template<> struct CanProxyAdaptor<IncompleteArrayType>;
+template<> struct CanProxyAdaptor<VariableArrayType>;
+template<> struct CanProxyAdaptor<DependentSizedArrayType>;
 
 template<>
 struct CanProxyAdaptor<DependentSizedExtVectorType>
@@ -746,6 +704,9 @@
 template<typename T>
 template<typename U>
 CanProxy<U> CanQual<T>::getAs() const {
+  ArrayType_cannot_be_used_with_getAs<U> at;
+  (void)at;
+
   if (Stored.isNull())
     return CanProxy<U>();
 
@@ -758,6 +719,9 @@
 template<typename T>
 template<typename U>
 CanProxy<U> CanQual<T>::castAs() const {
+  ArrayType_cannot_be_used_with_getAs<U> at;
+  (void)at;
+
   assert(!Stored.isNull() && isa<U>(Stored.getTypePtr()));
   return CanQual<U>::CreateUnsafe(Stored);
 }

Modified: cfe/trunk/lib/Rewrite/Frontend/RewriteModernObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/Frontend/RewriteModernObjC.cpp?rev=170081&r1=170080&r2=170081&view=diff
==============================================================================
--- cfe/trunk/lib/Rewrite/Frontend/RewriteModernObjC.cpp (original)
+++ cfe/trunk/lib/Rewrite/Frontend/RewriteModernObjC.cpp Wed Dec 12 19:43:21 2012
@@ -3842,16 +3842,16 @@
     Result += " : "; Result += utostr(fieldDecl->getBitWidthValue(*Context));
   }
   else if (EleboratedType && Type->isArrayType()) {
-    CanQualType CType = Context->getCanonicalType(Type);
-    while (isa<ArrayType>(CType)) {
-      if (const ConstantArrayType *CAT = Context->getAsConstantArrayType(CType)) {
+    const ArrayType *AT = Context->getAsArrayType(Type);
+    do {
+      if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) {
         Result += "[";
         llvm::APInt Dim = CAT->getSize();
         Result += utostr(Dim.getZExtValue());
         Result += "]";
       }
-      CType = CType->getAs<ArrayType>()->getElementType();
-    }
+      AT = Context->getAsArrayType(AT->getElementType());
+    } while (AT);
   }
   
   Result += ";\n";

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=170081&r1=170080&r2=170081&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Dec 12 19:43:21 2012
@@ -2456,19 +2456,17 @@
     //   absence of a major array bound (8.3.4).
     else if (Old->getType()->isIncompleteArrayType() &&
              New->getType()->isArrayType()) {
-      CanQual<ArrayType> OldArray
-        = Context.getCanonicalType(Old->getType())->getAs<ArrayType>();
-      CanQual<ArrayType> NewArray
-        = Context.getCanonicalType(New->getType())->getAs<ArrayType>();
-      if (OldArray->getElementType() == NewArray->getElementType())
+      const ArrayType *OldArray = Context.getAsArrayType(Old->getType());
+      const ArrayType *NewArray = Context.getAsArrayType(New->getType());
+      if (Context.hasSameType(OldArray->getElementType(),
+                              NewArray->getElementType()))
         MergedT = New->getType();
     } else if (Old->getType()->isArrayType() &&
              New->getType()->isIncompleteArrayType()) {
-      CanQual<ArrayType> OldArray
-        = Context.getCanonicalType(Old->getType())->getAs<ArrayType>();
-      CanQual<ArrayType> NewArray
-        = Context.getCanonicalType(New->getType())->getAs<ArrayType>();
-      if (OldArray->getElementType() == NewArray->getElementType())
+      const ArrayType *OldArray = Context.getAsArrayType(Old->getType());
+      const ArrayType *NewArray = Context.getAsArrayType(New->getType());
+      if (Context.hasSameType(OldArray->getElementType(),
+                              NewArray->getElementType()))
         MergedT = Old->getType();
     } else if (New->getType()->isObjCObjectPointerType()
                && Old->getType()->isObjCObjectPointerType()) {

Modified: cfe/trunk/test/SemaCXX/array-bound-merge.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/array-bound-merge.cpp?rev=170081&r1=170080&r2=170081&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/array-bound-merge.cpp (original)
+++ cfe/trunk/test/SemaCXX/array-bound-merge.cpp Wed Dec 12 19:43:21 2012
@@ -9,3 +9,6 @@
 int c[] = {1,2}; // expected-error {{excess elements in array initializer}}
 
 int d[1][]; // expected-error {{array has incomplete element type 'int []'}}
+
+extern const int e[2]; // expected-note {{previous definition is here}}
+int e[] = { 1 }; // expected-error {{redefinition of 'e' with a different type: 'int []' vs 'const int [2]'}}

Modified: cfe/trunk/test/SemaTemplate/instantiate-init.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-init.cpp?rev=170081&r1=170080&r2=170081&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-init.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiate-init.cpp Wed Dec 12 19:43:21 2012
@@ -94,7 +94,7 @@
   const Data<T> Description<T>::data[] = {{ 1 }}; // expected-error{{cannot initialize a member subobject of type 'int *' with an rvalue of type 'int'}}
 
   template<>
-  Data<float*> Description<float*>::data[];
+  const Data<float*> Description<float*>::data[];
 
   void test() {
     integral_c<1> ic1 = array_lengthof(Description<int>::data);





More information about the cfe-commits mailing list