aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-05-14 20:32:39 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-05-14 20:32:39 +0000
commit3b5904ba83fc9b968b1cd6f1ce78d01bfd6e8686 (patch)
treeee67c8f251bd35eb2b82ca1271d8ac36339c0aa8
parente1e96a6201168c232a06ec81685f948e05fddd39 (diff)
Emit an error when trying to @encode an incomplete type.
There are APIs, e.g. [NSValue valueWithBytes:objCType:], which use the encoding to find out the size of an object pointed to by a pointer. Make things safer by making it illegal to @encode incomplete types. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@131364 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--include/clang/Sema/Sema.h2
-rw-r--r--lib/Sema/SemaExprObjC.cpp8
-rw-r--r--test/SemaObjC/exprs.m10
4 files changed, 20 insertions, 2 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index ea1ef56010..b40aa61ba5 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2869,6 +2869,8 @@ def err_objc_pointer_cxx_catch_fragile : Error<
"exception model">;
def err_objc_object_catch : Error<
"can't catch an Objective C object by value">;
+def err_incomplete_type_objc_at_encode : Error<
+ "'@encode' of incomplete type %0">;
def warn_setter_getter_impl_required : Warning<
"property %0 requires method %1 to be defined - "
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 6265c67c07..d1487cc317 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -3105,7 +3105,7 @@ public:
Expr **Strings,
unsigned NumStrings);
- Expr *BuildObjCEncodeExpression(SourceLocation AtLoc,
+ ExprResult BuildObjCEncodeExpression(SourceLocation AtLoc,
TypeSourceInfo *EncodedTypeInfo,
SourceLocation RParenLoc);
ExprResult BuildCXXMemberCallExpr(Expr *Exp, NamedDecl *FoundDecl,
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index 2a262f0939..3444cb5a49 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -119,7 +119,7 @@ ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs,
return new (Context) ObjCStringLiteral(S, Ty, AtLocs[0]);
}
-Expr *Sema::BuildObjCEncodeExpression(SourceLocation AtLoc,
+ExprResult Sema::BuildObjCEncodeExpression(SourceLocation AtLoc,
TypeSourceInfo *EncodedTypeInfo,
SourceLocation RParenLoc) {
QualType EncodedType = EncodedTypeInfo->getType();
@@ -127,6 +127,12 @@ Expr *Sema::BuildObjCEncodeExpression(SourceLocation AtLoc,
if (EncodedType->isDependentType())
StrTy = Context.DependentTy;
else {
+ if (!EncodedType->getAsArrayTypeUnsafe()) // Incomplete array is handled.
+ if (RequireCompleteType(AtLoc, EncodedType,
+ PDiag(diag::err_incomplete_type_objc_at_encode)
+ << EncodedTypeInfo->getTypeLoc().getSourceRange()))
+ return ExprError();
+
std::string Str;
Context.getObjCEncodingForType(EncodedType, Str);
diff --git a/test/SemaObjC/exprs.m b/test/SemaObjC/exprs.m
index d7c122356f..2b505e0eae 100644
--- a/test/SemaObjC/exprs.m
+++ b/test/SemaObjC/exprs.m
@@ -32,3 +32,13 @@ void test3(Object *o) {
// this is ok.
__sync_bool_compare_and_swap(&g, 0, o);
}
+
+@class Incomplete_ObjC_class;
+struct Incomplete_struct; // expected-note {{forward declaration}}
+
+void test_encode() {
+ (void)@encode(Incomplete_ObjC_class); // expected-error {{incomplete type}}
+ (void)@encode(struct Incomplete_struct); // expected-error {{incomplete type}}
+ (void)@encode(Incomplete_ObjC_class*);
+ (void)@encode(id);
+}