The bots look healthy after the change, thanks!
2013/6/30 Richard Smith <[email protected]>: > Thanks for the speedy revert; reinstated with a fix in r185281. We're > now very nearly completely ignoring this rule in the standard (except > when a global *variable* conflicts with an extern "C" declaration, > when we still error because the mangled names are the same in some > circumstances). If this is still a problem, we can downgrade the > diagnostic to an extension in the MS ABI (where I believe even global > variables get mangled names). > > On Sat, Jun 29, 2013 at 8:23 AM, Reid Kleckner <[email protected]> wrote: >> I know, I yelled at him in person yesterday. :) He said the logic should >> probably be disabled for -fms-compatibility. But I'm OK with letting him >> fix that and roll it back in. >> >> >> On Sat, 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
