r216301 - Objective-C. Warn when @encode'ing provides an incomplete

Fariborz Jahanian fjahanian at apple.com
Fri Aug 22 16:17:52 PDT 2014


Author: fjahanian
Date: Fri Aug 22 18:17:52 2014
New Revision: 216301

URL: http://llvm.org/viewvc/llvm-project?rev=216301&view=rev
Log:
Objective-C. Warn when @encode'ing provides an incomplete
type encoding because in certain cases, such as for vector
types, because we still haven't designed encoding for them.
rdar://9255564

Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/Sema/SemaExprObjC.cpp
    cfe/trunk/test/SemaObjC/encode-typeof-test.m

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=216301&r1=216300&r2=216301&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Fri Aug 22 18:17:52 2014
@@ -1379,7 +1379,8 @@ public:
   ///
   /// If \p Field is specified then record field names are also encoded.
   void getObjCEncodingForType(QualType T, std::string &S,
-                              const FieldDecl *Field=nullptr) const;
+                              const FieldDecl *Field=nullptr,
+                              QualType *NotEncodedT=nullptr) const;
 
   /// \brief Emit the Objective-C property type encoding for the given
   /// type \p T into \p S.
@@ -2275,12 +2276,14 @@ private:
                                   bool StructField = false,
                                   bool EncodeBlockParameters = false,
                                   bool EncodeClassNames = false,
-                                  bool EncodePointerToObjCTypedef = false) const;
+                                  bool EncodePointerToObjCTypedef = false,
+                                  QualType *NotEncodedT=nullptr) const;
 
   // Adds the encoding of the structure's members.
   void getObjCEncodingForStructureImpl(RecordDecl *RD, std::string &S,
                                        const FieldDecl *Field,
-                                       bool includeVBases = true) const;
+                                       bool includeVBases = true,
+                                       QualType *NotEncodedT=nullptr) const;
 public:
   // Adds the encoding of a method parameter or return type.
   void getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT,

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=216301&r1=216300&r2=216301&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Aug 22 18:17:52 2014
@@ -2195,6 +2195,9 @@ def warn_type_attribute_wrong_type : War
   "'%0' only applies to %select{function|pointer|"
   "Objective-C object or block pointer}1 types; type here is %2">,
   InGroup<IgnoredAttributes>;
+def warn_incomplete_encoded_type : Warning<
+  "encoding of %0 type is incomplete because %1 component has unknown encoding">,
+  InGroup<DiagGroup<"encode-type">>;
 def warn_attribute_requires_functions_or_static_globals : Warning<
   "%0 only applies to variables with static storage duration and functions">,
   InGroup<IgnoredAttributes>;

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=216301&r1=216300&r2=216301&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Fri Aug 22 18:17:52 2014
@@ -5097,13 +5097,15 @@ void ASTContext::getLegacyIntegralTypeEn
 }
 
 void ASTContext::getObjCEncodingForType(QualType T, std::string& S,
-                                        const FieldDecl *Field) const {
+                                        const FieldDecl *Field,
+                                        QualType *NotEncodedT) const {
   // We follow the behavior of gcc, expanding structures which are
   // directly pointed to, and expanding embedded structures. Note that
   // these rules are sufficient to prevent recursive encoding of the
   // same type.
   getObjCEncodingForTypeImpl(T, S, true, true, Field,
-                             true /* outermost type */);
+                             true /* outermost type */, false, false,
+                             false, false, false, NotEncodedT);
 }
 
 void ASTContext::getObjCEncodingForPropertyType(QualType T,
@@ -5229,7 +5231,8 @@ void ASTContext::getObjCEncodingForTypeI
                                             bool StructField,
                                             bool EncodeBlockParameters,
                                             bool EncodeClassNames,
-                                            bool EncodePointerToObjCTypedef) const {
+                                            bool EncodePointerToObjCTypedef,
+                                            QualType *NotEncodedT) const {
   CanQualType CT = getCanonicalType(T);
   switch (CT->getTypeClass()) {
   case Type::Builtin:
@@ -5245,16 +5248,14 @@ void ASTContext::getObjCEncodingForTypeI
   case Type::Complex: {
     const ComplexType *CT = T->castAs<ComplexType>();
     S += 'j';
-    getObjCEncodingForTypeImpl(CT->getElementType(), S, false, false, nullptr,
-                               false, false);
+    getObjCEncodingForTypeImpl(CT->getElementType(), S, false, false, nullptr);
     return;
   }
 
   case Type::Atomic: {
     const AtomicType *AT = T->castAs<AtomicType>();
     S += 'A';
-    getObjCEncodingForTypeImpl(AT->getValueType(), S, false, false, nullptr,
-                               false, false);
+    getObjCEncodingForTypeImpl(AT->getValueType(), S, false, false, nullptr);
     return;
   }
 
@@ -5325,7 +5326,8 @@ void ASTContext::getObjCEncodingForTypeI
     getLegacyIntegralTypeEncoding(PointeeTy);
 
     getObjCEncodingForTypeImpl(PointeeTy, S, false, ExpandPointedToStructures,
-                               nullptr);
+                               nullptr, false, false, false, false, false, false,
+                               NotEncodedT);
     return;
   }
 
@@ -5353,7 +5355,9 @@ void ASTContext::getObjCEncodingForTypeI
       }
 
       getObjCEncodingForTypeImpl(AT->getElementType(), S,
-                                 false, ExpandStructures, FD);
+                                 false, ExpandStructures, FD,
+                                 false, false, false, false, false, false,
+                                 NotEncodedT);
       S += ']';
     }
     return;
@@ -5385,7 +5389,7 @@ void ASTContext::getObjCEncodingForTypeI
     if (ExpandStructures) {
       S += '=';
       if (!RDecl->isUnion()) {
-        getObjCEncodingForStructureImpl(RDecl, S, FD);
+        getObjCEncodingForStructureImpl(RDecl, S, FD, true, NotEncodedT);
       } else {
         for (const auto *Field : RDecl->fields()) {
           if (FD) {
@@ -5404,7 +5408,8 @@ void ASTContext::getObjCEncodingForTypeI
             getObjCEncodingForTypeImpl(qt, S, false, true,
                                        FD, /*OutermostType*/false,
                                        /*EncodingProperty*/false,
-                                       /*StructField*/true);
+                                       /*StructField*/true,
+                                       false, false, false, NotEncodedT);
           }
         }
       }
@@ -5424,7 +5429,8 @@ void ASTContext::getObjCEncodingForTypeI
       getObjCEncodingForTypeImpl(
           FT->getReturnType(), S, ExpandPointedToStructures, ExpandStructures,
           FD, false /* OutermostType */, EncodingProperty,
-          false /* StructField */, EncodeBlockParameters, EncodeClassNames);
+          false /* StructField */, EncodeBlockParameters, EncodeClassNames, false,
+                                 NotEncodedT);
       // Block self
       S += "@?";
       // Block parameters
@@ -5433,7 +5439,8 @@ void ASTContext::getObjCEncodingForTypeI
           getObjCEncodingForTypeImpl(
               I, S, ExpandPointedToStructures, ExpandStructures, FD,
               false /* OutermostType */, EncodingProperty,
-              false /* StructField */, EncodeBlockParameters, EncodeClassNames);
+              false /* StructField */, EncodeBlockParameters, EncodeClassNames,
+                                     false, NotEncodedT);
       }
       S += '>';
     }
@@ -5475,7 +5482,8 @@ void ASTContext::getObjCEncodingForTypeI
       else
         getObjCEncodingForTypeImpl(Field->getType(), S, false, true, FD,
                                    false, false, false, false, false,
-                                   EncodePointerToObjCTypedef);
+                                   EncodePointerToObjCTypedef,
+                                   NotEncodedT);
     }
     S += '}';
     return;
@@ -5562,19 +5570,21 @@ void ASTContext::getObjCEncodingForTypeI
   // gcc just blithely ignores member pointers.
   // FIXME: we shoul do better than that.  'M' is available.
   case Type::MemberPointer:
-    return;
-  
+  // This matches gcc's encoding, even though technically it is insufficient.
+  //FIXME. We should do a better job than gcc.
   case Type::Vector:
   case Type::ExtVector:
-    // This matches gcc's encoding, even though technically it is
-    // insufficient.
-    // FIXME. We should do a better job than gcc.
-    return;
-
+  // Until we have a coherent encoding of these three types, issue warning.
+    { if (NotEncodedT)
+        *NotEncodedT = T;
+      return;
+    }
+      
+  // We could see an undeduced auto type here during error recovery.
+  // Just ignore it.
   case Type::Auto:
-    // We could see an undeduced auto type here during error recovery.
-    // Just ignore it.
     return;
+  
 
 #define ABSTRACT_TYPE(KIND, BASE)
 #define TYPE(KIND, BASE)
@@ -5593,7 +5603,8 @@ void ASTContext::getObjCEncodingForTypeI
 void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
                                                  std::string &S,
                                                  const FieldDecl *FD,
-                                                 bool includeVBases) const {
+                                                 bool includeVBases,
+                                                 QualType *NotEncodedT) const {
   assert(RDecl && "Expected non-null RecordDecl");
   assert(!RDecl->isUnion() && "Should not be called for unions");
   if (!RDecl->getDefinition())
@@ -5697,7 +5708,8 @@ void ASTContext::getObjCEncodingForStruc
       // in the initial structure. Note that this differs from gcc which
       // expands virtual bases each time one is encountered in the hierarchy,
       // making the encoding type bigger than it really is.
-      getObjCEncodingForStructureImpl(base, S, FD, /*includeVBases*/false);
+      getObjCEncodingForStructureImpl(base, S, FD, /*includeVBases*/false,
+                                      NotEncodedT);
       assert(!base->isEmpty());
 #ifndef NDEBUG
       CurOffs += toBits(getASTRecordLayout(base).getNonVirtualSize());
@@ -5721,7 +5733,8 @@ void ASTContext::getObjCEncodingForStruc
         getObjCEncodingForTypeImpl(qt, S, false, true, FD,
                                    /*OutermostType*/false,
                                    /*EncodingProperty*/false,
-                                   /*StructField*/true);
+                                   /*StructField*/true,
+                                   false, false, false, NotEncodedT);
 #ifndef NDEBUG
         CurOffs += getTypeSize(field->getType());
 #endif

Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=216301&r1=216300&r2=216301&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Fri Aug 22 18:17:52 2014
@@ -995,7 +995,11 @@ ExprResult Sema::BuildObjCEncodeExpressi
         return ExprError();
 
     std::string Str;
-    Context.getObjCEncodingForType(EncodedType, Str);
+    QualType NotEncodedT;
+    Context.getObjCEncodingForType(EncodedType, Str, nullptr, &NotEncodedT);
+    if (!NotEncodedT.isNull())
+      Diag(AtLoc, diag::warn_incomplete_encoded_type)
+        << EncodedType << NotEncodedT;
 
     // The type of @encode is the same as the type of the corresponding string,
     // which is an array type.

Modified: cfe/trunk/test/SemaObjC/encode-typeof-test.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/encode-typeof-test.m?rev=216301&r1=216300&r2=216301&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/encode-typeof-test.m (original)
+++ cfe/trunk/test/SemaObjC/encode-typeof-test.m Fri Aug 22 18:17:52 2014
@@ -24,3 +24,22 @@ int main()
     int i;
     typeof(@encode(typeof(i))) e = @encode(typeof(Intf)); // expected-warning {{initializer-string for char array is too long}}
 }
+
+// rdar://9255564
+typedef short short8 __attribute__((ext_vector_type(8)));
+
+struct foo {
+ char a;
+ int b;
+ long c;
+ short8 d;
+ int array[4];
+ short int bitfield1:5;
+ unsigned short bitfield2:11;
+ char *string;
+};
+
+const char *RetEncode () {
+ return @encode(struct foo); // expected-warning {{encoding of 'struct foo' type is incomplete because 'short8' (vector of 8 'short' values) component has unknown encoding}}
+}
+





More information about the cfe-commits mailing list