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