I am seeing a similar issue on Darwin with a bunch of programs in the test-suite (for example Shootout-C++/heapsort.cpp).
Michael On Jun 29, 2013, at 1:36 AM, Timur Iskhodzhanov <[email protected]> wrote: > Hi Richard, > > This has broken compilation of <windows.h>: > > C:\Program Files (x86)\Microsoft Visual Studio > 10.0\VC\INCLUDE\stdio.h:276:47: error: declaration of 'gets_s' in > global scope conflicts with declaration with C language linkage > __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_0(char *, gets_s, char, _Buffer) > ^ > C:\Program Files (x86)\Microsoft Visual Studio > 10.0\VC\INCLUDE\crtdefs.h:587:27: note: expanded from macro > '__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_0' > _ReturnType __CRTDECL _FuncName(_DstType (&_Dst)[_Size]) > _CRT_SECURE_CPP_NOTHROW \ > ^ > C:\Program Files (x86)\Microsoft Visual Studio > 10.0\VC\INCLUDE\stdio.h:274:24: note: declared with C language linkage > here > _CRTIMP char * __cdecl gets_s(_Out_z_cap_(_Size) char * _Buf, _In_ > rsize_t _Size); > ^ > C:\Program Files (x86)\Microsoft Visual Studio > 10.0\VC\INCLUDE\stdio.h:319:52: error: declaration of '_snprintf_s' in > global scope conflicts with declaration with C language linkage > __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2_ARGLIST(int, _snprintf_s, > _vsnprintf_s, _Deref_post_z_ char, _Dest, _In_ size_t, _MaxCount, > _In_z_ _Printf_format_string_ const char *,_Format) > ^ > C:\Program Files (x86)\Microsoft Visual Studio > 10.0\VC\INCLUDE\crtdefs.h:704:27: note: expanded from macro > '__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2_ARGLIST' > _ReturnType __CRTDECL _FuncName(_DstType (&_Dst)[_Size], _TType1 > _TArg1, _TType2 _TArg2, ...) _CRT_SECURE_CPP_NOTHROW \ > ^ > C:\Program Files (x86)\Microsoft Visual Studio > 10.0\VC\INCLUDE\stdio.h:318:52: note: declared with C language linkage > here > _Check_return_opt_ _CRTIMP_ALTERNATIVE int __cdecl > _snprintf_s(_Out_z_bytecap_(_SizeInBytes) char * _DstBuf, _In_ size_t > _SizeInBytes, _In_ size_t _MaxCount, _In_z_ _Printf_format_string_ > const char * _Format, ...); > --- > > I'm going to revert your change to make the bots greener over the weekend. > Please investigate how extern "C" is used here and add tests to > prevent new regressions. > > -- > Timur > > 2013/6/29 Richard Smith <[email protected]>: >> Author: rsmith >> Date: Fri Jun 28 17:03:51 2013 >> New Revision: 185229 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=185229&view=rev >> Log: >> PR7927, PR16247: Reimplement handling of matching extern "C" declarations >> across scopes. >> >> When we declare an extern "C" name that is not a redeclaration of an entity >> in >> the same scope, check whether it redeclares some extern "C" entity from >> another >> scope, and if not, check whether it conflicts with a (non-extern-"C") entity >> in >> the translation unit. >> >> When we declare a name in the translation unit that is not a redeclaration, >> check whether it conflicts with any extern "C" entities (possibly from other >> scopes). >> >> Modified: >> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td >> cfe/trunk/lib/Sema/SemaDecl.cpp >> cfe/trunk/lib/Sema/SemaOverload.cpp >> cfe/trunk/test/CXX/class.access/class.friend/p1.cpp >> cfe/trunk/test/Sema/overloadable.c >> cfe/trunk/test/SemaCXX/extern-c.cpp >> cfe/trunk/test/SemaCXX/friend.cpp >> cfe/trunk/test/SemaCXX/linkage-spec.cpp >> cfe/trunk/test/SemaCXX/linkage2.cpp >> >> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=185229&r1=185228&r2=185229&view=diff >> ============================================================================== >> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) >> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Jun 28 17:03:51 >> 2013 >> @@ -3493,6 +3493,11 @@ def err_static_non_static : Error< >> "static declaration of %0 follows non-static declaration">; >> def err_different_language_linkage : Error< >> "declaration of %0 has a different language linkage">; >> +def err_extern_c_global_conflict : Error< >> + "declaration of %1 %select{with C language linkage|in global scope}0 " >> + "conflicts with declaration %select{in global scope|with C language >> linkage}0">; >> +def note_extern_c_global_conflict : Note< >> + "declared %select{in global scope|with C language linkage}0 here">; >> def warn_weak_import : Warning < >> "an already-declared variable is made a weak_import declaration %0">; >> def warn_static_non_static : ExtWarn< >> >> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=185229&r1=185228&r2=185229&view=diff >> ============================================================================== >> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) >> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Jun 28 17:03:51 2013 >> @@ -4359,10 +4359,14 @@ TryToFixInvalidVariablyModifiedTypeSourc >> /// function-scope declarations. >> void >> Sema::RegisterLocallyScopedExternCDecl(NamedDecl *ND, Scope *S) { >> - assert( >> - !ND->getLexicalDeclContext()->getRedeclContext()->isTranslationUnit() >> && >> - "Decl is not a locally-scoped decl!"); >> + if (!getLangOpts().CPlusPlus && >> + ND->getLexicalDeclContext()->getRedeclContext()->isTranslationUnit()) >> + // Don't need to track declarations in the TU in C. >> + return; >> + >> // Note that we have a locally-scoped external with this name. >> + // FIXME: There can be multiple such declarations if they are functions >> marked >> + // __attribute__((overloadable)) declared in function scope in C. >> LocallyScopedExternCDecls[ND->getDeclName()] = ND; >> } >> >> @@ -4681,6 +4685,32 @@ static bool isFunctionDefinitionDiscarde >> return isC99Inline; >> } >> >> +/// Determine whether a variable is extern "C" prior to attaching >> +/// an initializer. We can't just call isExternC() here, because that >> +/// will also compute and cache whether the declaration is externally >> +/// visible, which might change when we attach the initializer. >> +/// >> +/// This can only be used if the declaration is known to not be a >> +/// redeclaration of an internal linkage declaration. >> +/// >> +/// For instance: >> +/// >> +/// auto x = []{}; >> +/// >> +/// Attaching the initializer here makes this declaration not externally >> +/// visible, because its type has internal linkage. >> +/// >> +/// FIXME: This is a hack. >> +template<typename T> >> +static bool isIncompleteDeclExternC(Sema &S, const T *D) { >> + if (S.getLangOpts().CPlusPlus) { >> + // In C++, the overloadable attribute negates the effects of extern "C". >> + if (!D->isInExternCContext() || D->template hasAttr<OverloadableAttr>()) >> + return false; >> + } >> + return D->isExternC(); >> +} >> + >> static bool shouldConsiderLinkage(const VarDecl *VD) { >> const DeclContext *DC = VD->getDeclContext()->getRedeclContext(); >> if (DC->isFunctionOrMethod()) >> @@ -5070,16 +5100,10 @@ Sema::ActOnVariableDeclarator(Scope *S, >> ProcessPragmaWeak(S, NewVD); >> checkAttributesAfterMerging(*this, *NewVD); >> >> - // If this is the first declaration of an extern C variable that is not >> - // declared directly in the translation unit, update the map of such >> - // variables. >> - if (!CurContext->getRedeclContext()->isTranslationUnit() && >> - !NewVD->getPreviousDecl() && !NewVD->isInvalidDecl() && >> - // FIXME: We only check isExternC if we're in an extern C context, >> - // to avoid computing and caching an 'externally visible' flag which >> - // could change if the variable's type is not visible. >> - (!getLangOpts().CPlusPlus || NewVD->isInExternCContext()) && >> - NewVD->isExternC()) >> + // If this is the first declaration of an extern C variable, update >> + // the map of such variables. >> + if (!NewVD->getPreviousDecl() && !NewVD->isInvalidDecl() && >> + isIncompleteDeclExternC(*this, NewVD)) >> RegisterLocallyScopedExternCDecl(NewVD, S); >> >> return NewVD; >> @@ -5180,30 +5204,120 @@ void Sema::CheckShadow(Scope *S, VarDecl >> CheckShadow(S, D, R); >> } >> >> +/// Check for conflict between this global or extern "C" declaration and >> +/// previous global or extern "C" declarations. This is only used in C++. >> template<typename T> >> -static bool mayConflictWithNonVisibleExternC(const T *ND) { >> - const DeclContext *DC = ND->getDeclContext(); >> - if (DC->getRedeclContext()->isTranslationUnit()) >> - return true; >> +static bool checkGlobalOrExternCConflict( >> + Sema &S, const T *ND, bool IsGlobal, LookupResult &Previous) { >> + assert(S.getLangOpts().CPlusPlus && "only C++ has extern \"C\""); >> + NamedDecl *Prev = S.findLocallyScopedExternCDecl(ND->getDeclName()); >> + >> + if (!Prev && IsGlobal && !isIncompleteDeclExternC(S, ND)) { >> + // The common case: this global doesn't conflict with any extern "C" >> + // declaration. >> + return false; >> + } >> >> - // We know that is the first decl we see, other than function local >> - // extern C ones. If this is C++ and the decl is not in a extern C context >> - // it cannot have C language linkage. Avoid calling isExternC in that >> case. >> - // We need to this because of code like >> - // >> - // namespace { struct bar {}; } >> - // auto foo = bar(); >> - // >> - // This code runs before the init of foo is set, and therefore before >> - // the type of foo is known. Not knowing the type we cannot know its >> linkage >> - // unless it is in an extern C block. >> - if (!ND->isInExternCContext()) { >> - const ASTContext &Context = ND->getASTContext(); >> - if (Context.getLangOpts().CPlusPlus) >> + if (Prev) { >> + if (!IsGlobal || isIncompleteDeclExternC(S, ND)) { >> + // Both the old and new declarations have C language linkage. This is >> a >> + // redeclaration. >> + Previous.clear(); >> + Previous.addDecl(Prev); >> + return true; >> + } >> + >> + // This is a global, non-extern "C" declaration, and there is a previous >> + // non-global extern "C" declaration. Diagnose. >> + } else { >> + // The declaration is extern "C". Check for any declaration in the >> + // translation unit which might conflict. >> + if (IsGlobal) { >> + // We have already performed the lookup into the translation unit. >> + IsGlobal = false; >> + for (LookupResult::iterator I = Previous.begin(), E = Previous.end(); >> + I != E; ++I) { >> + if (isa<VarDecl>(*I) || isa<FunctionDecl>(*I)) { >> + Prev = *I; >> + break; >> + } >> + } >> + } else { >> + DeclContext::lookup_result R = >> + S.Context.getTranslationUnitDecl()->lookup(ND->getDeclName()); >> + for (DeclContext::lookup_result::iterator I = R.begin(), E = R.end(); >> + I != E; ++I) { >> + if (isa<VarDecl>(*I) || isa<FunctionDecl>(*I)) { >> + Prev = *I; >> + break; >> + } >> + // FIXME: If we have any other entity with this name in global >> scope, >> + // the declaration is ill-formed, but that is a defect: it breaks >> the >> + // 'stat' hack, for instance. >> + } >> + } >> + >> + if (!Prev) >> return false; >> } >> >> - return ND->isExternC(); >> + // Use the first declaration's location to ensure we point at something >> which >> + // is lexically inside an extern "C" linkage-spec. >> + assert(Prev && "should have found a previous declaration to diagnose"); >> + if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Prev)) >> + Prev = FD->getFirstDeclaration(); >> + else >> + Prev = cast<VarDecl>(Prev)->getFirstDeclaration(); >> + >> + S.Diag(ND->getLocation(), diag::err_extern_c_global_conflict) >> + << IsGlobal << ND; >> + S.Diag(Prev->getLocation(), diag::note_extern_c_global_conflict) >> + << IsGlobal; >> + return false; >> +} >> + >> +/// Apply special rules for handling extern "C" declarations. Returns \c >> true >> +/// if we have found that this is a redeclaration of some prior entity. >> +/// >> +/// Per C++ [dcl.link]p6: >> +/// Two declarations [for a function or variable] with C language linkage >> +/// with the same name that appear in different scopes refer to the same >> +/// [entity]. An entity with C language linkage shall not be declared with >> +/// the same name as an entity in global scope. >> +template<typename T> >> +static bool checkForConflictWithNonVisibleExternC(Sema &S, const T *ND, >> + LookupResult &Previous) { >> + if (!S.getLangOpts().CPlusPlus) { >> + // In C, when declaring a global variable, look for a corresponding >> 'extern' >> + // variable declared in function scope. >> + // >> + // FIXME: The corresponding case in C++ does not work. We should >> instead >> + // set the semantic DC for an extern local variable to be the innermost >> + // enclosing namespace, and ensure they are only found by redeclaration >> + // lookup. >> + if (ND->getDeclContext()->getRedeclContext()->isTranslationUnit()) { >> + if (NamedDecl *Prev = >> S.findLocallyScopedExternCDecl(ND->getDeclName())) { >> + Previous.clear(); >> + Previous.addDecl(Prev); >> + return true; >> + } >> + } >> + return false; >> + } >> + >> + // A declaration in the translation unit can conflict with an extern "C" >> + // declaration. >> + if (ND->getDeclContext()->getRedeclContext()->isTranslationUnit()) >> + return checkGlobalOrExternCConflict(S, ND, /*IsGlobal*/true, Previous); >> + >> + // An extern "C" declaration can conflict with a declaration in the >> + // translation unit or can be a redeclaration of an extern "C" declaration >> + // in another scope. >> + if (isIncompleteDeclExternC(S,ND)) >> + return checkGlobalOrExternCConflict(S, ND, /*IsGlobal*/false, Previous); >> + >> + // Neither global nor extern "C": nothing to do. >> + return false; >> } >> >> void Sema::CheckVariableDeclarationType(VarDecl *NewVD) { >> @@ -5386,14 +5500,9 @@ bool Sema::CheckVariableDeclaration(VarD >> // The most important point here is that we're not allowed to >> // update our understanding of the type according to declarations >> // not in scope. >> - bool PreviousWasHidden = false; >> - if (Previous.empty() && mayConflictWithNonVisibleExternC(NewVD)) { >> - if (NamedDecl *ExternCPrev = >> - findLocallyScopedExternCDecl(NewVD->getDeclName())) { >> - Previous.addDecl(ExternCPrev); >> - PreviousWasHidden = true; >> - } >> - } >> + bool PreviousWasHidden = >> + Previous.empty() && >> + checkForConflictWithNonVisibleExternC(*this, NewVD, Previous); >> >> // Filter out any non-conflicting previous declarations. >> filterNonConflictingPreviousDecls(Context, NewVD, Previous); >> @@ -6625,12 +6734,10 @@ Sema::ActOnFunctionDeclarator(Scope *S, >> // marking the function. >> AddCFAuditedAttribute(NewFD); >> >> - // If this is the first declaration of an extern C variable that is not >> - // declared directly in the translation unit, update the map of such >> - // variables. >> - if (!CurContext->getRedeclContext()->isTranslationUnit() && >> - !NewFD->getPreviousDecl() && NewFD->isExternC() && >> - !NewFD->isInvalidDecl()) >> + // If this is the first declaration of an extern C variable, update >> + // the map of such variables. >> + if (!NewFD->getPreviousDecl() && !NewFD->isInvalidDecl() && >> + isIncompleteDeclExternC(*this, NewFD)) >> RegisterLocallyScopedExternCDecl(NewFD, S); >> >> // Set this FunctionDecl's range up to the right paren. >> @@ -6734,15 +6841,6 @@ bool Sema::CheckFunctionDeclaration(Scop >> assert(!NewFD->getResultType()->isVariablyModifiedType() >> && "Variably modified return types are not handled here"); >> >> - // Check for a previous declaration of this name. >> - if (Previous.empty() && mayConflictWithNonVisibleExternC(NewFD)) { >> - // Since we did not find anything by this name, look for a non-visible >> - // extern "C" declaration with the same name. >> - if (NamedDecl *ExternCPrev = >> - findLocallyScopedExternCDecl(NewFD->getDeclName())) >> - Previous.addDecl(ExternCPrev); >> - } >> - >> // Filter out any non-conflicting previous declarations. >> filterNonConflictingPreviousDecls(Context, NewFD, Previous); >> >> @@ -6796,6 +6894,34 @@ bool Sema::CheckFunctionDeclaration(Scop >> } >> } >> } >> + >> + // Check for a previous extern "C" declaration with this name. >> + if (!Redeclaration && >> + checkForConflictWithNonVisibleExternC(*this, NewFD, Previous)) { >> + filterNonConflictingPreviousDecls(Context, NewFD, Previous); >> + if (!Previous.empty()) { >> + // This is an extern "C" declaration with the same name as a previous >> + // declaration, and thus redeclares that entity... >> + Redeclaration = true; >> + OldDecl = Previous.getFoundDecl(); >> + >> + // ... except in the presence of __attribute__((overloadable)). >> + if (OldDecl->hasAttr<OverloadableAttr>()) { >> + if (!getLangOpts().CPlusPlus && >> !NewFD->hasAttr<OverloadableAttr>()) { >> + Diag(NewFD->getLocation(), >> diag::err_attribute_overloadable_missing) >> + << Redeclaration << NewFD; >> + Diag(Previous.getFoundDecl()->getLocation(), >> + diag::note_attribute_overloadable_prev_overload); >> + NewFD->addAttr(::new (Context) OverloadableAttr(SourceLocation(), >> + Context)); >> + } >> + if (IsOverload(NewFD, cast<FunctionDecl>(OldDecl), false)) { >> + Redeclaration = false; >> + OldDecl = 0; >> + } >> + } >> + } >> + } >> >> // C++11 [dcl.constexpr]p8: >> // A constexpr specifier for a non-static member function that is not >> >> Modified: cfe/trunk/lib/Sema/SemaOverload.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=185229&r1=185228&r2=185229&view=diff >> ============================================================================== >> --- cfe/trunk/lib/Sema/SemaOverload.cpp (original) >> +++ cfe/trunk/lib/Sema/SemaOverload.cpp Fri Jun 28 17:03:51 2013 >> @@ -977,21 +977,12 @@ Sema::CheckOverload(Scope *S, FunctionDe >> return Ovl_Overload; >> } >> >> -static bool canBeOverloaded(const FunctionDecl &D) { >> - if (D.getAttr<OverloadableAttr>()) >> - return true; >> - if (D.isExternC()) >> - return false; >> - >> - // Main cannot be overloaded (basic.start.main). >> - if (D.isMain()) >> +bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old, >> + bool UseUsingDeclRules) { >> + // C++ [basic.start.main]p2: This function shall not be overloaded. >> + if (New->isMain()) >> return false; >> >> - return true; >> -} >> - >> -static bool shouldTryToOverload(Sema &S, FunctionDecl *New, FunctionDecl >> *Old, >> - bool UseUsingDeclRules) { >> FunctionTemplateDecl *OldTemplate = Old->getDescribedFunctionTemplate(); >> FunctionTemplateDecl *NewTemplate = New->getDescribedFunctionTemplate(); >> >> @@ -1002,8 +993,8 @@ static bool shouldTryToOverload(Sema &S, >> return true; >> >> // Is the function New an overload of the function Old? >> - QualType OldQType = S.Context.getCanonicalType(Old->getType()); >> - QualType NewQType = S.Context.getCanonicalType(New->getType()); >> + QualType OldQType = Context.getCanonicalType(Old->getType()); >> + QualType NewQType = Context.getCanonicalType(New->getType()); >> >> // Compare the signatures (C++ 1.3.10) of the two functions to >> // determine whether they are overloads. If we find any mismatch >> @@ -1024,7 +1015,7 @@ static bool shouldTryToOverload(Sema &S, >> if (OldQType != NewQType && >> (OldType->getNumArgs() != NewType->getNumArgs() || >> OldType->isVariadic() != NewType->isVariadic() || >> - !S.FunctionArgTypesAreEqual(OldType, NewType))) >> + !FunctionArgTypesAreEqual(OldType, NewType))) >> return true; >> >> // C++ [temp.over.link]p4: >> @@ -1040,9 +1031,9 @@ static bool shouldTryToOverload(Sema &S, >> // However, we don't consider either of these when deciding whether >> // a member introduced by a shadow declaration is hidden. >> if (!UseUsingDeclRules && NewTemplate && >> - >> (!S.TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(), >> - >> OldTemplate->getTemplateParameters(), >> - false, S.TPL_TemplateMatch) || >> + (!TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(), >> + OldTemplate->getTemplateParameters(), >> + false, TPL_TemplateMatch) || >> OldType->getResultType() != NewType->getResultType())) >> return true; >> >> @@ -1068,9 +1059,9 @@ static bool shouldTryToOverload(Sema &S, >> // declarations with the same name, the same >> parameter-type-list, and >> // the same template parameter lists cannot be overloaded if any >> of >> // them, but not all, have a ref-qualifier (8.3.5). >> - S.Diag(NewMethod->getLocation(), diag::err_ref_qualifier_overload) >> + Diag(NewMethod->getLocation(), diag::err_ref_qualifier_overload) >> << NewMethod->getRefQualifier() << OldMethod->getRefQualifier(); >> - S.Diag(OldMethod->getLocation(), diag::note_previous_declaration); >> + Diag(OldMethod->getLocation(), diag::note_previous_declaration); >> } >> return true; >> } >> @@ -1080,7 +1071,7 @@ static bool shouldTryToOverload(Sema &S, >> // or non-static member function). Add it now, on the assumption that >> this >> // is a redeclaration of OldMethod. >> unsigned NewQuals = NewMethod->getTypeQualifiers(); >> - if (!S.getLangOpts().CPlusPlus1y && NewMethod->isConstexpr() && >> + if (!getLangOpts().CPlusPlus1y && NewMethod->isConstexpr() && >> !isa<CXXConstructorDecl>(NewMethod)) >> NewQuals |= Qualifiers::Const; >> if (OldMethod->getTypeQualifiers() != NewQuals) >> @@ -1091,19 +1082,6 @@ static bool shouldTryToOverload(Sema &S, >> return false; >> } >> >> -bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old, >> - bool UseUsingDeclRules) { >> - if (!shouldTryToOverload(*this, New, Old, UseUsingDeclRules)) >> - return false; >> - >> - // If both of the functions are extern "C", then they are not >> - // overloads. >> - if (!canBeOverloaded(*Old) && !canBeOverloaded(*New)) >> - return false; >> - >> - return true; >> -} >> - >> /// \brief Checks availability of the function depending on the current >> /// function context. Inside an unavailable function, unavailability is >> ignored. >> /// >> >> Modified: cfe/trunk/test/CXX/class.access/class.friend/p1.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class.access/class.friend/p1.cpp?rev=185229&r1=185228&r2=185229&view=diff >> ============================================================================== >> --- cfe/trunk/test/CXX/class.access/class.friend/p1.cpp (original) >> +++ cfe/trunk/test/CXX/class.access/class.friend/p1.cpp Fri Jun 28 17:03:51 >> 2013 >> @@ -287,22 +287,22 @@ namespace test9 { >> >> // PR7230 >> namespace test10 { >> - extern "C" void f(void); >> - extern "C" void g(void); >> + extern "C" void test10_f(void); >> + extern "C" void test10_g(void); >> >> namespace NS { >> class C { >> void foo(void); // expected-note {{declared private here}} >> - friend void test10::f(void); >> + friend void test10::test10_f(void); >> }; >> static C* bar; >> } >> >> - void f(void) { >> + void test10_f(void) { >> NS::bar->foo(); >> } >> >> - void g(void) { >> + void test10_g(void) { >> NS::bar->foo(); // expected-error {{private member}} >> } >> } >> >> Modified: cfe/trunk/test/Sema/overloadable.c >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/overloadable.c?rev=185229&r1=185228&r2=185229&view=diff >> ============================================================================== >> --- cfe/trunk/test/Sema/overloadable.c (original) >> +++ cfe/trunk/test/Sema/overloadable.c Fri Jun 28 17:03:51 2013 >> @@ -69,3 +69,18 @@ void test() { >> f0(); >> f1(); >> } >> + >> +void before_local_1(int) __attribute__((overloadable)); // expected-note >> {{here}} >> +void before_local_2(int); // expected-note {{here}} >> +void before_local_3(int) __attribute__((overloadable)); >> +void local() { >> + void before_local_1(char); // expected-error {{must have the >> 'overloadable' attribute}} >> + void before_local_2(char) __attribute__((overloadable)); // >> expected-error {{conflicting types}} >> + void before_local_3(char) __attribute__((overloadable)); >> + void after_local_1(char); // expected-note {{here}} >> + void after_local_2(char) __attribute__((overloadable)); // expected-note >> {{here}} >> + void after_local_3(char) __attribute__((overloadable)); >> +} >> +void after_local_1(int) __attribute__((overloadable)); // expected-error >> {{conflicting types}} >> +void after_local_2(int); // expected-error {{must have the 'overloadable' >> attribute}} >> +void after_local_3(int) __attribute__((overloadable)); >> >> Modified: cfe/trunk/test/SemaCXX/extern-c.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/extern-c.cpp?rev=185229&r1=185228&r2=185229&view=diff >> ============================================================================== >> --- cfe/trunk/test/SemaCXX/extern-c.cpp (original) >> +++ cfe/trunk/test/SemaCXX/extern-c.cpp Fri Jun 28 17:03:51 2013 >> @@ -3,20 +3,20 @@ >> namespace test1 { >> extern "C" { >> void test1_f() { >> - void test1_g(int); // expected-note {{previous declaration is here}} >> + void test1_g(int); // expected-note {{declared with C language >> linkage here}} >> } >> } >> } >> -int test1_g(int); // expected-error {{functions that differ only in their >> return type cannot be overloaded}} >> +int test1_g(int); // expected-error {{declaration of 'test1_g' in global >> scope conflicts with declaration with C language linkage}} >> >> namespace test2 { >> extern "C" { >> void test2_f() { >> - extern int test2_x; // expected-note {{previous definition is here}} >> + extern int test2_x; // expected-note {{declared with C language >> linkage here}} >> } >> } >> } >> -float test2_x; // expected-error {{redefinition of 'test2_x' with a >> different type: 'float' vs 'int'}} >> +float test2_x; // expected-error {{declaration of 'test2_x' in global scope >> conflicts with declaration with C language linkage}} >> >> namespace test3 { >> extern "C" { >> @@ -31,18 +31,18 @@ namespace test3 { >> >> extern "C" { >> void test4_f() { >> - extern int test4_b; // expected-note {{previous definition is here}} >> + extern int test4_b; // expected-note {{declared with C language linkage >> here}} >> } >> } >> -static float test4_b; // expected-error {{redefinition of 'test4_b' with a >> different type: 'float' vs 'int'}} >> +static float test4_b; // expected-error {{declaration of 'test4_b' in >> global scope conflicts with declaration with C language linkage}} >> >> extern "C" { >> void test5_f() { >> - extern int test5_b; // expected-note {{previous definition is here}} >> + extern int test5_b; // expected-note {{declared with C language linkage >> here}} >> } >> } >> extern "C" { >> - static float test5_b; // expected-error {{redefinition of 'test5_b' with >> a different type: 'float' vs 'int'}} >> + static float test5_b; // expected-error {{declaration of 'test5_b' in >> global scope conflicts with declaration with C language linkage}} >> } >> >> extern "C" { >> @@ -69,11 +69,11 @@ namespace linkage { >> } >> } >> namespace from_outer { >> - void linkage_from_outer_1(); >> + void linkage_from_outer_1(); // expected-note {{previous}} >> void linkage_from_outer_2(); // expected-note {{previous}} >> extern "C" { >> - void linkage_from_outer_1(int); // expected-note {{previous}} >> - void linkage_from_outer_1(); // expected-error {{conflicting types}} >> + void linkage_from_outer_1(int); >> + void linkage_from_outer_1(); // expected-error {{different language >> linkage}} >> void linkage_from_outer_2(); // expected-error {{different language >> linkage}} >> } >> } >> @@ -98,11 +98,44 @@ namespace linkage { >> } >> } >> >> -void lookup_in_global_f(); >> +void lookup_in_global_f(); // expected-note {{here}} >> namespace lookup_in_global { >> void lookup_in_global_f(); >> + void lookup_in_global_g(); >> extern "C" { >> - // FIXME: We should reject this. >> - void lookup_in_global_f(int); >> + void lookup_in_global_f(int); // expected-error {{conflicts with >> declaration in global scope}} >> + void lookup_in_global_g(int); // expected-note {{here}} >> } >> } >> +void lookup_in_global_g(); // expected-error {{conflicts with declaration >> with C language linkage}} >> + >> +namespace N1 { >> + extern "C" int different_kind_1; // expected-note {{here}} >> + extern "C" void different_kind_2(); // expected-note {{here}} >> +} >> +namespace N2 { >> + extern "C" void different_kind_1(); // expected-error {{different kind of >> symbol}} >> + extern "C" int different_kind_2; // expected-error {{different kind of >> symbol}} >> +} >> + >> +extern "C" { >> + struct stat {}; >> + void stat(struct stat); >> +} >> +namespace X { >> + extern "C" { >> + void stat(struct ::stat); >> + } >> +} >> + >> +extern "C" void name_with_using_decl_1(int); >> +namespace using_decl { >> + void name_with_using_decl_1(); >> + void name_with_using_decl_2(); >> + void name_with_using_decl_3(); >> +} >> +using using_decl::name_with_using_decl_1; >> +using using_decl::name_with_using_decl_2; >> +extern "C" void name_with_using_decl_2(int); >> +extern "C" void name_with_using_decl_3(int); >> +using using_decl::name_with_using_decl_3; >> >> Modified: cfe/trunk/test/SemaCXX/friend.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/friend.cpp?rev=185229&r1=185228&r2=185229&view=diff >> ============================================================================== >> --- cfe/trunk/test/SemaCXX/friend.cpp (original) >> +++ cfe/trunk/test/SemaCXX/friend.cpp Fri Jun 28 17:03:51 2013 >> @@ -134,7 +134,7 @@ namespace test6_3 { >> namespace test7 { >> extern "C" { >> class X { >> - friend int f() { return 42; } >> + friend int test7_f() { return 42; } >> }; >> } >> } >> >> Modified: cfe/trunk/test/SemaCXX/linkage-spec.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/linkage-spec.cpp?rev=185229&r1=185228&r2=185229&view=diff >> ============================================================================== >> --- cfe/trunk/test/SemaCXX/linkage-spec.cpp (original) >> +++ cfe/trunk/test/SemaCXX/linkage-spec.cpp Fri Jun 28 17:03:51 2013 >> @@ -41,20 +41,32 @@ namespace pr5430 { >> using namespace pr5430; >> extern "C" void pr5430::func(void) { } >> >> -// PR5404 >> -int f2(char *) >> +// PR5405 >> +int f2(char *) // expected-note {{here}} >> { >> return 0; >> } >> >> extern "C" >> { >> - int f2(int) >> + int f2(int) // expected-error {{with C language linkage conflicts with >> declaration in global scope}} >> { >> return f2((char *)0); >> } >> } >> >> +namespace PR5405 { >> + int f2b(char *) { >> + return 0; >> + } >> + >> + extern "C" { >> + int f2b(int) { >> + return f2b((char *)0); // ok >> + } >> + } >> +} >> + >> // PR6991 >> extern "C" typedef int (*PutcFunc_t)(int); >> >> @@ -117,3 +129,28 @@ namespace pr14958 { >> >> extern "C" void PR16167; // expected-error {{variable has incomplete type >> 'void'}} >> extern void PR16167_0; // expected-error {{variable has incomplete type >> 'void'}} >> + >> +// PR7927 >> +enum T_7927 { >> + E_7927 >> +}; >> + >> +extern "C" void f_pr7927(int); >> + >> +namespace { >> + extern "C" void f_pr7927(int); >> + >> + void foo_pr7927() { >> + f_pr7927(E_7927); >> + f_pr7927(0); >> + ::f_pr7927(E_7927); >> + ::f_pr7927(0); >> + } >> +} >> + >> +void bar_pr7927() { >> + f_pr7927(E_7927); >> + f_pr7927(0); >> + ::f_pr7927(E_7927); >> + ::f_pr7927(0); >> +} >> >> Modified: cfe/trunk/test/SemaCXX/linkage2.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/linkage2.cpp?rev=185229&r1=185228&r2=185229&view=diff >> ============================================================================== >> --- cfe/trunk/test/SemaCXX/linkage2.cpp (original) >> +++ cfe/trunk/test/SemaCXX/linkage2.cpp Fri Jun 28 17:03:51 2013 >> @@ -201,3 +201,15 @@ namespace test18 { >> } >> void *h() { return f(); } >> } >> + >> +extern "C" void pr16247_foo(int); // expected-note {{here}} >> +static void pr16247_foo(double); // expected-error {{conflicts with >> declaration with C language linkage}} >> +void pr16247_foo(int) {} >> +void pr16247_foo(double) {} >> + >> +namespace PR16247 { >> + extern "C" void pr16247_bar(int); >> + static void pr16247_bar(double); >> + void pr16247_bar(int) {} >> + void pr16247_bar(double) {} >> +} >> >> >> _______________________________________________ >> cfe-commits mailing list >> [email protected] >> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
