diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -730,11 +730,11 @@ if (CondExpr && !CondExpr->isTypeDependent()) { // We have already converted the expression to an integral or enumeration - // type, when we parsed the switch condition. If we don't have an - // appropriate type now, enter the switch scope but remember that it's - // invalid. - assert(CondExpr->getType()->isIntegralOrEnumerationType() && - "invalid condition type"); + // type, when we parsed the switch condition. There are cases where we don't + // have an appropriate type, e.g. a typo-expr Cond was corrected to an + // inappropriate-type expr, we just return an error. + if (!CondExpr->getType()->isIntegralOrEnumerationType()) + return StmtError(); if (CondExpr->isKnownToHaveBooleanValue()) { // switch(bool_expr) {...} is often a programmer error, e.g. // switch(n && mask) { ... } // Doh - should be "n & mask". diff --git a/clang/test/Parser/switch-typo-correction.cpp b/clang/test/Parser/switch-typo-correction.cpp new file mode 100644 --- /dev/null +++ b/clang/test/Parser/switch-typo-correction.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace c { double xxx; } // expected-note{{'c::xxx' declared here}} +namespace d { float xxx; } +namespace z { namespace xxx {} } + +void crash() { + switch (xxx) {} // expected-error{{use of undeclared identifier 'xxx'; did you mean }} +}