aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2010-07-17 20:43:49 +0000
committerEli Friedman <eli.friedman@gmail.com>2010-07-17 20:43:49 +0000
commit8d438087bd7120990663e4df78a9c9fdb02c5209 (patch)
tree1339b94788c9fee28e3e55606909a80d64f8bfb4
parentac0021ba802e193e0f9f8207768c7862c7603bc0 (diff)
Check for casts to an incomplete type in C. Improves diagnostics for cast to
incomplete union (PR5692) and incomplete enum, and fixes obscure accepts-invalid on cast to incomplete struct. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@108630 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--lib/Sema/SemaExpr.cpp4
-rw-r--r--test/Sema/cast-incomplete.c14
3 files changed, 20 insertions, 0 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index ef34fb8ef5..9f83406c72 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2650,6 +2650,8 @@ def err_typecheck_cond_expect_scalar : Error<
"used type %0 where arithmetic or pointer type is required">;
def ext_typecheck_cond_one_void : Extension<
"C99 forbids conditional expressions with only one void side">;
+def err_typecheck_cast_to_incomplete : Error<
+ "cast to incomplete type %0">;
def ext_typecheck_cast_nonscalar : Extension<
"C99 forbids casting nonscalar type %0 to the same type">;
def ext_typecheck_cast_to_union : Extension<"C99 forbids casts to union type">;
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index d798d9d0e5..2d3aaf6edc 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -3891,6 +3891,10 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr,
return false;
}
+ if (RequireCompleteType(TyR.getBegin(), castType,
+ diag::err_typecheck_cast_to_incomplete))
+ return true;
+
if (!castType->isScalarType() && !castType->isVectorType()) {
if (Context.hasSameUnqualifiedType(castType, castExpr->getType()) &&
(castType->isStructureType() || castType->isUnionType())) {
diff --git a/test/Sema/cast-incomplete.c b/test/Sema/cast-incomplete.c
new file mode 100644
index 0000000000..dd10e00d44
--- /dev/null
+++ b/test/Sema/cast-incomplete.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only %s -verify
+// PR5692
+
+enum x; // expected-note {{forward declaration}}
+extern struct y a; // expected-note {{forward declaration}}
+extern union z b; // expected-note 2 {{forward declaration}}
+
+void foo() {
+ (enum x)1; // expected-error {{cast to incomplete type}}
+ (struct y)a; // expected-error {{cast to incomplete type}}
+ (union z)b; // expected-error {{cast to incomplete type}}
+ (union z)1; // expected-error {{cast to incomplete type}}
+}
+