From aa71567ba4b8a10e9a7d668bf93e35413d7260a8 Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Wed, 29 May 2013 00:56:45 +0000 Subject: [PATCH] Disallow extern decls of type void in C++ mode C++ and C differ with respect to the handling of extern void declarations. Enforce the C++ behavior in C++ mode. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@182814 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDecl.cpp | 14 +++++++++----- test/SemaCXX/linkage-spec.cpp | 2 ++ test/SemaCXX/qualified-id-lookup.cpp | 2 +- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 49c8fe5e71..05748f72f4 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -5271,11 +5271,15 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) { NewVD->setTypeSourceInfo(FixedTInfo); } - if (T->isVoidType() && NewVD->isThisDeclarationADefinition()) { - Diag(NewVD->getLocation(), diag::err_typecheck_decl_incomplete_type) - << T; - NewVD->setInvalidDecl(); - return; + if (T->isVoidType()) { + // C++98 [dcl.stc]p5: The extern specifier can be applied only to the names + // of objects and functions. + if (NewVD->isThisDeclarationADefinition() || getLangOpts().CPlusPlus) { + Diag(NewVD->getLocation(), diag::err_typecheck_decl_incomplete_type) + << T; + NewVD->setInvalidDecl(); + return; + } } if (!NewVD->hasLocalStorage() && NewVD->hasAttr()) { diff --git a/test/SemaCXX/linkage-spec.cpp b/test/SemaCXX/linkage-spec.cpp index 504df0d35c..7681c7d847 100644 --- a/test/SemaCXX/linkage-spec.cpp +++ b/test/SemaCXX/linkage-spec.cpp @@ -114,3 +114,5 @@ namespace pr14958 { } int js::ObjectClass; } + +extern "C" void PR16167; // expected-error {{variable has incomplete type 'void'}} diff --git a/test/SemaCXX/qualified-id-lookup.cpp b/test/SemaCXX/qualified-id-lookup.cpp index a14193cc7a..26f1d7c472 100644 --- a/test/SemaCXX/qualified-id-lookup.cpp +++ b/test/SemaCXX/qualified-id-lookup.cpp @@ -149,6 +149,6 @@ namespace PR6830 { } namespace pr12339 { - extern "C" void i; + extern "C" void i; // expected-error{{variable has incomplete type 'void'}} pr12339::FOO // expected-error{{no type named 'FOO' in namespace 'pr12339'}} } // expected-error{{expected unqualified-id}} -- 2.50.1