aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--lib/Sema/SemaStmt.cpp7
-rw-r--r--test/SemaCXX/switch.cpp7
3 files changed, 16 insertions, 0 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 95f65805d6..4032285f8d 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2299,6 +2299,8 @@ def note_switch_conversion : Note<
"conversion to %select{integral|enumeration}0 type %1">;
def err_switch_explicit_conversion : Error<
"switch condition type %0 requires explicit conversion to %1">;
+def err_switch_incomplete_class_type : Error<
+ "switch condition has incomplete class type %0">;
def warn_empty_if_body : Warning<
"if statement has empty body">, InGroup<EmptyBody>;
def err_va_start_used_in_non_variadic_function : Error<
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index b674a1738c..ad3376b9c8 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -391,6 +391,13 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, StmtArg Switch,
// conversion is used in place of the original condition for the remainder
// of this section. Integral promotions are performed.
if (!CondExpr->isTypeDependent()) {
+ // Make sure that the condition expression has a complete type,
+ // otherwise we'll never find any conversions.
+ if (RequireCompleteType(SwitchLoc, CondType,
+ PDiag(diag::err_switch_incomplete_class_type)
+ << CondExpr->getSourceRange()))
+ return StmtError();
+
llvm::SmallVector<CXXConversionDecl *, 4> ViableConversions;
llvm::SmallVector<CXXConversionDecl *, 4> ExplicitConversions;
if (const RecordType *RecordTy = CondType->getAs<RecordType>()) {
diff --git a/test/SemaCXX/switch.cpp b/test/SemaCXX/switch.cpp
index 2f2f2a9587..003d5b8b9c 100644
--- a/test/SemaCXX/switch.cpp
+++ b/test/SemaCXX/switch.cpp
@@ -33,3 +33,10 @@ void x2() {
switch (B()) { // expected-error{{multiple conversions}}
}
}
+
+struct C; // expected-note{{forward declaration}}
+
+void x3(C &c) {
+ switch (c) { // expected-error{{incomplete class type}}
+ }
+}