Index: clang/include/clang/Basic/DiagnosticParseKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticParseKinds.td +++ clang/include/clang/Basic/DiagnosticParseKinds.td @@ -809,6 +809,8 @@ def err_explicit_spec_non_template : Error< "explicit %select{specialization|instantiation}0 of " "%select{non-|undeclared }3template %1 %2">; +def err_explicit_declaration_not_class : Error< + "'explicit' outside class declaration">; def err_default_template_template_parameter_not_template : Error< "default template argument for a template template parameter must be a class " Index: clang/lib/Parse/ParseDecl.cpp =================================================================== --- clang/lib/Parse/ParseDecl.cpp +++ clang/lib/Parse/ParseDecl.cpp @@ -3706,12 +3706,15 @@ } break; case tok::kw_explicit: { + if (DSContext != DeclSpecContext::DSC_class) { + Diag(Tok.getLocation(), diag::err_explicit_declaration_not_class); + } SourceLocation ExplicitLoc = Loc; SourceLocation CloseParenLoc; ExplicitSpecifier ExplicitSpec(nullptr, ExplicitSpecKind::ResolvedTrue); ConsumedEnd = ExplicitLoc; ConsumeToken(); // kw_explicit - if (Tok.is(tok::l_paren)) { + if (Tok.is(tok::l_paren) && DSContext == DeclSpecContext::DSC_class) { if (getLangOpts().CPlusPlus20 || isExplicitBool() == TPResult::True) { Diag(Tok.getLocation(), getLangOpts().CPlusPlus20 ? diag::warn_cxx17_compat_explicit_bool Index: clang/test/Misc/explicit.c =================================================================== --- /dev/null +++ clang/test/Misc/explicit.c @@ -0,0 +1,3 @@ +// Don't crash when explicit specifier is used outside of the class. +int b = 0; +int foo () { explicit ( && b );}