diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/AnalysisBasedWarnings.cpp | 63 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/JumpDiagnostics.cpp | 34 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaCast.cpp | 9 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaChecking.cpp | 4 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaCodeComplete.cpp | 4 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaDeclAttr.cpp | 3 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp | 122 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp | 23 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaLookup.cpp | 20 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaStmtAsm.cpp | 16 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp | 13 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaType.cpp | 44 |
12 files changed, 223 insertions, 132 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/AnalysisBasedWarnings.cpp b/contrib/llvm/tools/clang/lib/Sema/AnalysisBasedWarnings.cpp index d697ecb..97f4a8d 100644 --- a/contrib/llvm/tools/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -1463,7 +1463,7 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { PartialDiagnosticAt FNote(CurrentFunction->getBody()->getLocStart(), S.PDiag(diag::note_thread_warning_in_fun) << CurrentFunction->getNameAsString()); - ONS.push_back(FNote); + ONS.push_back(std::move(FNote)); } return ONS; } @@ -1477,7 +1477,7 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { PartialDiagnosticAt FNote(CurrentFunction->getBody()->getLocStart(), S.PDiag(diag::note_thread_warning_in_fun) << CurrentFunction->getNameAsString()); - ONS.push_back(FNote); + ONS.push_back(std::move(FNote)); } return ONS; } @@ -1490,7 +1490,7 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { if (!Loc.isValid()) Loc = FunLocation; PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind << LockName); - Warnings.push_back(DelayedDiag(Warning, getNotes())); + Warnings.emplace_back(std::move(Warning), getNotes()); } public: @@ -1516,7 +1516,7 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { void handleInvalidLockExp(StringRef Kind, SourceLocation Loc) override { PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_cannot_resolve_lock) << Loc); - Warnings.push_back(DelayedDiag(Warning, getNotes())); + Warnings.emplace_back(std::move(Warning), getNotes()); } void handleUnmatchedUnlock(StringRef Kind, Name LockName, @@ -1532,7 +1532,7 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_unlock_kind_mismatch) << Kind << LockName << Received << Expected); - Warnings.push_back(DelayedDiag(Warning, getNotes())); + Warnings.emplace_back(std::move(Warning), getNotes()); } void handleDoubleLock(StringRef Kind, Name LockName, SourceLocation Loc) override { @@ -1566,10 +1566,10 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { if (LocLocked.isValid()) { PartialDiagnosticAt Note(LocLocked, S.PDiag(diag::note_locked_here) << Kind); - Warnings.push_back(DelayedDiag(Warning, getNotes(Note))); + Warnings.emplace_back(std::move(Warning), getNotes(Note)); return; } - Warnings.push_back(DelayedDiag(Warning, getNotes())); + Warnings.emplace_back(std::move(Warning), getNotes()); } void handleExclusiveAndShared(StringRef Kind, Name LockName, @@ -1580,7 +1580,7 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { << Kind << LockName); PartialDiagnosticAt Note(Loc2, S.PDiag(diag::note_lock_exclusive_and_shared) << Kind << LockName); - Warnings.push_back(DelayedDiag(Warning, getNotes(Note))); + Warnings.emplace_back(std::move(Warning), getNotes(Note)); } void handleNoMutexHeld(StringRef Kind, const NamedDecl *D, @@ -1593,7 +1593,7 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { diag::warn_var_deref_requires_any_lock; PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << D->getNameAsString() << getLockKindFromAccessKind(AK)); - Warnings.push_back(DelayedDiag(Warning, getNotes())); + Warnings.emplace_back(std::move(Warning), getNotes()); } void handleMutexNotHeld(StringRef Kind, const NamedDecl *D, @@ -1628,9 +1628,9 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { PartialDiagnosticAt VNote(D->getLocation(), S.PDiag(diag::note_guarded_by_declared_here) << D->getNameAsString()); - Warnings.push_back(DelayedDiag(Warning, getNotes(Note, VNote))); + Warnings.emplace_back(std::move(Warning), getNotes(Note, VNote)); } else - Warnings.push_back(DelayedDiag(Warning, getNotes(Note))); + Warnings.emplace_back(std::move(Warning), getNotes(Note)); } else { switch (POK) { case POK_VarAccess: @@ -1656,9 +1656,9 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { PartialDiagnosticAt Note(D->getLocation(), S.PDiag(diag::note_guarded_by_declared_here) << D->getNameAsString()); - Warnings.push_back(DelayedDiag(Warning, getNotes(Note))); + Warnings.emplace_back(std::move(Warning), getNotes(Note)); } else - Warnings.push_back(DelayedDiag(Warning, getNotes())); + Warnings.emplace_back(std::move(Warning), getNotes()); } } @@ -1667,7 +1667,7 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_acquire_requires_negative_cap) << Kind << LockName << Neg); - Warnings.push_back(DelayedDiag(Warning, getNotes())); + Warnings.emplace_back(std::move(Warning), getNotes()); } @@ -1675,20 +1675,20 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { SourceLocation Loc) override { PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_fun_excludes_mutex) << Kind << FunName << LockName); - Warnings.push_back(DelayedDiag(Warning, getNotes())); + Warnings.emplace_back(std::move(Warning), getNotes()); } void handleLockAcquiredBefore(StringRef Kind, Name L1Name, Name L2Name, SourceLocation Loc) override { PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_acquired_before) << Kind << L1Name << L2Name); - Warnings.push_back(DelayedDiag(Warning, getNotes())); + Warnings.emplace_back(std::move(Warning), getNotes()); } void handleBeforeAfterCycle(Name L1Name, SourceLocation Loc) override { PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_acquired_before_after_cycle) << L1Name); - Warnings.push_back(DelayedDiag(Warning, getNotes())); + Warnings.emplace_back(std::move(Warning), getNotes()); } void enterFunction(const FunctionDecl* FD) override { @@ -1732,8 +1732,8 @@ public: StringRef VariableName) override { PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_loop_state_mismatch) << VariableName); - - Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); + + Warnings.emplace_back(std::move(Warning), OptionalNotes()); } void warnParamReturnTypestateMismatch(SourceLocation Loc, @@ -1744,8 +1744,8 @@ public: PartialDiagnosticAt Warning(Loc, S.PDiag( diag::warn_param_return_typestate_mismatch) << VariableName << ExpectedState << ObservedState); - - Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); + + Warnings.emplace_back(std::move(Warning), OptionalNotes()); } void warnParamTypestateMismatch(SourceLocation Loc, StringRef ExpectedState, @@ -1753,16 +1753,16 @@ public: PartialDiagnosticAt Warning(Loc, S.PDiag( diag::warn_param_typestate_mismatch) << ExpectedState << ObservedState); - - Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); + + Warnings.emplace_back(std::move(Warning), OptionalNotes()); } void warnReturnTypestateForUnconsumableType(SourceLocation Loc, StringRef TypeName) override { PartialDiagnosticAt Warning(Loc, S.PDiag( diag::warn_return_typestate_for_unconsumable_type) << TypeName); - - Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); + + Warnings.emplace_back(std::move(Warning), OptionalNotes()); } void warnReturnTypestateMismatch(SourceLocation Loc, StringRef ExpectedState, @@ -1770,8 +1770,8 @@ public: PartialDiagnosticAt Warning(Loc, S.PDiag( diag::warn_return_typestate_mismatch) << ExpectedState << ObservedState); - - Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); + + Warnings.emplace_back(std::move(Warning), OptionalNotes()); } void warnUseOfTempInInvalidState(StringRef MethodName, StringRef State, @@ -1779,8 +1779,8 @@ public: PartialDiagnosticAt Warning(Loc, S.PDiag( diag::warn_use_of_temp_in_invalid_state) << MethodName << State); - - Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); + + Warnings.emplace_back(std::move(Warning), OptionalNotes()); } void warnUseInInvalidState(StringRef MethodName, StringRef VariableName, @@ -1788,8 +1788,8 @@ public: PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_use_in_invalid_state) << MethodName << VariableName << State); - - Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); + + Warnings.emplace_back(std::move(Warning), OptionalNotes()); } }; }}} @@ -1886,6 +1886,7 @@ AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P, AC.getCFGBuildOptions().AddImplicitDtors = true; AC.getCFGBuildOptions().AddTemporaryDtors = true; AC.getCFGBuildOptions().AddCXXNewAllocator = false; + AC.getCFGBuildOptions().AddCXXDefaultInitExprInCtors = true; // Force that certain expressions appear as CFGElements in the CFG. This // is used to speed up various analyses. diff --git a/contrib/llvm/tools/clang/lib/Sema/JumpDiagnostics.cpp b/contrib/llvm/tools/clang/lib/Sema/JumpDiagnostics.cpp index aac28be..6b9eb2a 100644 --- a/contrib/llvm/tools/clang/lib/Sema/JumpDiagnostics.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/JumpDiagnostics.cpp @@ -72,10 +72,10 @@ public: JumpScopeChecker(Stmt *Body, Sema &S); private: void BuildScopeInformation(Decl *D, unsigned &ParentScope); - void BuildScopeInformation(VarDecl *D, const BlockDecl *BDecl, + void BuildScopeInformation(VarDecl *D, const BlockDecl *BDecl, unsigned &ParentScope); void BuildScopeInformation(Stmt *S, unsigned &origParentScope); - + void VerifyJumps(); void VerifyIndirectJumps(); void NoteJumpIntoScopes(ArrayRef<unsigned> ToScopes); @@ -166,7 +166,7 @@ static ScopePair GetDiagForGotoScopeDecl(Sema &S, const Decl *D) { // A program that jumps from a point where a variable with automatic // storage duration is not in scope to a point where it is in scope // is ill-formed unless the variable has scalar type, class type with - // a trivial default constructor and a trivial destructor, a + // a trivial default constructor and a trivial destructor, a // cv-qualified version of one of these types, or an array of one of // the preceding types and is declared without an initializer. @@ -218,7 +218,7 @@ void JumpScopeChecker::BuildScopeInformation(Decl *D, unsigned &ParentScope) { D->getLocation())); ParentScope = Scopes.size()-1; } - + // If the decl has an initializer, walk it with the potentially new // scope we just installed. if (VarDecl *VD = dyn_cast<VarDecl>(D)) @@ -227,8 +227,8 @@ void JumpScopeChecker::BuildScopeInformation(Decl *D, unsigned &ParentScope) { } /// \brief Build scope information for a captured block literal variables. -void JumpScopeChecker::BuildScopeInformation(VarDecl *D, - const BlockDecl *BDecl, +void JumpScopeChecker::BuildScopeInformation(VarDecl *D, + const BlockDecl *BDecl, unsigned &ParentScope) { // exclude captured __block variables; there's no destructor // associated with the block literal for them. @@ -257,7 +257,7 @@ void JumpScopeChecker::BuildScopeInformation(VarDecl *D, SourceLocation Loc = D->getLocation(); if (Loc.isInvalid()) Loc = BDecl->getLocation(); - Scopes.push_back(GotoScope(ParentScope, + Scopes.push_back(GotoScope(ParentScope, Diags.first, Diags.second, Loc)); ParentScope = Scopes.size()-1; } @@ -272,11 +272,11 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned &origParentScope) // propagate out into the enclosing scope. Otherwise we have to worry // about block literals, which have the lifetime of their enclosing statement. unsigned independentParentScope = origParentScope; - unsigned &ParentScope = ((isa<Expr>(S) && !isa<StmtExpr>(S)) + unsigned &ParentScope = ((isa<Expr>(S) && !isa<StmtExpr>(S)) ? origParentScope : independentParentScope); bool SkipFirstSubStmt = false; - + // If we found a label, remember that it is in ParentScope scope. switch (S->getStmtClass()) { case Stmt::AddrLabelExprClass: @@ -307,7 +307,7 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned &origParentScope) SkipFirstSubStmt = true; } // Fall through - + case Stmt::GotoStmtClass: // Remember both what scope a goto is in as well as the fact that we have // it. This makes the second scan not have to walk the AST again. @@ -332,7 +332,7 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned &origParentScope) diag::note_protected_by_cxx_catch, diag::note_exits_cxx_catch, CS->getSourceRange().getBegin())); - BuildScopeInformation(CS->getHandlerBlock(), + BuildScopeInformation(CS->getHandlerBlock(), (newParentScope = Scopes.size()-1)); } return; @@ -354,14 +354,14 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned &origParentScope) diag::note_protected_by_seh_except, diag::note_exits_seh_except, Except->getSourceRange().getBegin())); - BuildScopeInformation(Except->getBlock(), + BuildScopeInformation(Except->getBlock(), (newParentScope = Scopes.size()-1)); } else if (SEHFinallyStmt *Finally = TS->getFinallyHandler()) { Scopes.push_back(GotoScope(ParentScope, diag::note_protected_by_seh_finally, diag::note_exits_seh_finally, Finally->getSourceRange().getBegin())); - BuildScopeInformation(Finally->getBlock(), + BuildScopeInformation(Finally->getBlock(), (newParentScope = Scopes.size()-1)); } @@ -377,7 +377,7 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned &origParentScope) SkipFirstSubStmt = false; continue; } - + Stmt *SubStmt = *CI; if (!SubStmt) continue; @@ -428,7 +428,7 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned &origParentScope) diag::note_exits_objc_catch, AC->getAtCatchLoc())); // @catches are nested and it isn't - BuildScopeInformation(AC->getCatchBody(), + BuildScopeInformation(AC->getCatchBody(), (newParentScope = Scopes.size()-1)); } @@ -443,7 +443,7 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned &origParentScope) continue; } - + unsigned newParentScope; // Disallow jumps into the protected statement of an @synchronized, but // allow jumps into the object expression it protects. @@ -459,7 +459,7 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned &origParentScope) diag::note_protected_by_objc_synchronized, diag::note_exits_objc_synchronized, AS->getAtSynchronizedLoc())); - BuildScopeInformation(AS->getSynchBody(), + BuildScopeInformation(AS->getSynchBody(), (newParentScope = Scopes.size()-1)); continue; } diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaCast.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaCast.cpp index 091e779..d9dc4df9 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaCast.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaCast.cpp @@ -1081,6 +1081,15 @@ static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr, Kind = CK_BitCast; return TC_Success; } + + // Microsoft permits static_cast from 'pointer-to-void' to + // 'pointer-to-function'. + if (!CStyle && Self.getLangOpts().MSVCCompat && + DestPointee->isFunctionType()) { + Self.Diag(OpRange.getBegin(), diag::ext_ms_cast_fn_obj) << OpRange; + Kind = CK_BitCast; + return TC_Success; + } } else if (DestType->isObjCObjectPointerType()) { // allow both c-style cast and static_cast of objective-c pointers as diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaChecking.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaChecking.cpp index 23a6fc3..c3b81b6 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaChecking.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaChecking.cpp @@ -1604,6 +1604,10 @@ ExprResult Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult, return ExprError(); } + // atomic_fetch_or takes a pointer to a volatile 'A'. We shouldn't let the + // volatile-ness of the pointee-type inject itself into the result or the + // other operands. + ValType.removeLocalVolatile(); QualType ResultType = ValType; if (Form == Copy || Form == GNUXchg || Form == Init) ResultType = Context.VoidTy; diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaCodeComplete.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaCodeComplete.cpp index 18d352b..fd97809 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaCodeComplete.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaCodeComplete.cpp @@ -1018,9 +1018,7 @@ void ResultBuilder::AddResult(Result R) { } /// \brief Enter into a new scope. -void ResultBuilder::EnterNewScope() { - ShadowMaps.push_back(ShadowMap()); -} +void ResultBuilder::EnterNewScope() { ShadowMaps.emplace_back(); } /// \brief Exit from the current scope. void ResultBuilder::ExitScope() { diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaDeclAttr.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaDeclAttr.cpp index 31fe055..1d04159 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaDeclAttr.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaDeclAttr.cpp @@ -3302,11 +3302,10 @@ static void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) { static void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) { if (hasDeclarator(D)) return; - const FunctionDecl *FD = dyn_cast<FunctionDecl>(D); // Diagnostic is emitted elsewhere: here we store the (valid) Attr // in the Decl node for syntactic reasoning, e.g., pretty-printing. CallingConv CC; - if (S.CheckCallingConvAttr(Attr, CC, FD)) + if (S.CheckCallingConvAttr(Attr, CC, /*FD*/nullptr)) return; if (!isa<ObjCMethodDecl>(D)) { diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp index b1dfe0e..c80ef2d 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp @@ -1345,57 +1345,6 @@ static bool findCircularInheritance(const CXXRecordDecl *Class, return false; } -/// \brief Perform propagation of DLL attributes from a derived class to a -/// templated base class for MS compatibility. -static void propagateDLLAttrToBaseClassTemplate( - Sema &S, CXXRecordDecl *Class, Attr *ClassAttr, - ClassTemplateSpecializationDecl *BaseTemplateSpec, SourceLocation BaseLoc) { - if (getDLLAttr( - BaseTemplateSpec->getSpecializedTemplate()->getTemplatedDecl())) { - // If the base class template has a DLL attribute, don't try to change it. - return; - } - - if (BaseTemplateSpec->getSpecializationKind() == TSK_Undeclared) { - // If the base class is not already specialized, we can do the propagation. - auto *NewAttr = cast<InheritableAttr>(ClassAttr->clone(S.getASTContext())); - NewAttr->setInherited(true); - BaseTemplateSpec->addAttr(NewAttr); - return; - } - - bool DifferentAttribute = false; - if (Attr *SpecializationAttr = getDLLAttr(BaseTemplateSpec)) { - if (!SpecializationAttr->isInherited()) { - // The template has previously been specialized or instantiated with an - // explicit attribute. We should not try to change it. - return; - } - if (SpecializationAttr->getKind() == ClassAttr->getKind()) { - // The specialization already has the right attribute. - return; - } - DifferentAttribute = true; - } - - // The template was previously instantiated or explicitly specialized without - // a dll attribute, or the template was previously instantiated with a - // different inherited attribute. It's too late for us to change the - // attribute, so warn that this is unsupported. - S.Diag(BaseLoc, diag::warn_attribute_dll_instantiated_base_class) - << BaseTemplateSpec->isExplicitSpecialization() << DifferentAttribute; - S.Diag(ClassAttr->getLocation(), diag::note_attribute); - if (BaseTemplateSpec->isExplicitSpecialization()) { - S.Diag(BaseTemplateSpec->getLocation(), - diag::note_template_class_explicit_specialization_was_here) - << BaseTemplateSpec; - } else { - S.Diag(BaseTemplateSpec->getPointOfInstantiation(), - diag::note_template_class_instantiation_was_here) - << BaseTemplateSpec; - } -} - /// \brief Check the validity of a C++ base class specifier. /// /// \returns a new CXXBaseSpecifier if well-formed, emits diagnostics @@ -1467,8 +1416,8 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class, if (Attr *ClassAttr = getDLLAttr(Class)) { if (auto *BaseTemplate = dyn_cast_or_null<ClassTemplateSpecializationDecl>( BaseType->getAsCXXRecordDecl())) { - propagateDLLAttrToBaseClassTemplate(*this, Class, ClassAttr, - BaseTemplate, BaseLoc); + propagateDLLAttrToBaseClassTemplate(Class, ClassAttr, BaseTemplate, + BaseLoc); } } } @@ -4791,8 +4740,9 @@ void Sema::checkClassLevelDLLAttribute(CXXRecordDecl *Class) { TemplateSpecializationKind TSK = Class->getTemplateSpecializationKind(); - // Don't dllexport explicit class template instantiation declarations. - if (ClassExported && TSK == TSK_ExplicitInstantiationDeclaration) { + // Ignore explicit dllexport on explicit class template instantiation declarations. + if (ClassExported && !ClassAttr->isInherited() && + TSK == TSK_ExplicitInstantiationDeclaration) { Class->dropAttr<DLLExportAttr>(); return; } @@ -4840,12 +4790,15 @@ void Sema::checkClassLevelDLLAttribute(CXXRecordDecl *Class) { } if (MD && ClassExported) { + if (TSK == TSK_ExplicitInstantiationDeclaration) + // Don't go any further if this is just an explicit instantiation + // declaration. + continue; + if (MD->isUserProvided()) { // Instantiate non-default class member functions ... // .. except for certain kinds of template specializations. - if (TSK == TSK_ExplicitInstantiationDeclaration) - continue; if (TSK == TSK_ImplicitInstantiation && !ClassAttr->isInherited()) continue; @@ -4876,6 +4829,61 @@ void Sema::checkClassLevelDLLAttribute(CXXRecordDecl *Class) { } } +/// \brief Perform propagation of DLL attributes from a derived class to a +/// templated base class for MS compatibility. +void Sema::propagateDLLAttrToBaseClassTemplate( + CXXRecordDecl *Class, Attr *ClassAttr, + ClassTemplateSpecializationDecl *BaseTemplateSpec, SourceLocation BaseLoc) { + if (getDLLAttr( + BaseTemplateSpec->getSpecializedTemplate()->getTemplatedDecl())) { + // If the base class template has a DLL attribute, don't try to change it. + return; + } + + auto TSK = BaseTemplateSpec->getSpecializationKind(); + if (!getDLLAttr(BaseTemplateSpec) && + (TSK == TSK_Undeclared || TSK == TSK_ExplicitInstantiationDeclaration || + TSK == TSK_ImplicitInstantiation)) { + // The template hasn't been instantiated yet (or it has, but only as an + // explicit instantiation declaration or implicit instantiation, which means + // we haven't codegenned any members yet), so propagate the attribute. + auto *NewAttr = cast<InheritableAttr>(ClassAttr->clone(getASTContext())); + NewAttr->setInherited(true); + BaseTemplateSpec->addAttr(NewAttr); + + // If the template is already instantiated, checkDLLAttributeRedeclaration() + // needs to be run again to work see the new attribute. Otherwise this will + // get run whenever the template is instantiated. + if (TSK != TSK_Undeclared) + checkClassLevelDLLAttribute(BaseTemplateSpec); + + return; + } + + if (getDLLAttr(BaseTemplateSpec)) { + // The template has already been specialized or instantiated with an + // attribute, explicitly or through propagation. We should not try to change + // it. + return; + } + + // The template was previously instantiated or explicitly specialized without + // a dll attribute, It's too late for us to add an attribute, so warn that + // this is unsupported. + Diag(BaseLoc, diag::warn_attribute_dll_instantiated_base_class) + << BaseTemplateSpec->isExplicitSpecialization(); + Diag(ClassAttr->getLocation(), diag::note_attribute); + if (BaseTemplateSpec->isExplicitSpecialization()) { + Diag(BaseTemplateSpec->getLocation(), + diag::note_template_class_explicit_specialization_was_here) + << BaseTemplateSpec; + } else { + Diag(BaseTemplateSpec->getPointOfInstantiation(), + diag::note_template_class_instantiation_was_here) + << BaseTemplateSpec; + } +} + /// \brief Perform semantic checks on a class definition that has been /// completing, introducing implicitly-declared members, checking for /// abstract types, etc. diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp index 7ab269c..b0bc231 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp @@ -1110,10 +1110,15 @@ static QualType handleFloatConversion(Sema &S, ExprResult &LHS, return RHSType; } - if (LHSFloat) + if (LHSFloat) { + // Half FP has to be promoted to float unless it is natively supported + if (LHSType->isHalfType() && !S.getLangOpts().NativeHalfType) + LHSType = S.Context.FloatTy; + return handleIntToFloatConversion(S, LHS, RHS, LHSType, RHSType, /*convertFloat=*/!IsCompAssign, /*convertInt=*/ true); + } assert(RHSFloat); return handleIntToFloatConversion(S, RHS, LHS, RHSType, LHSType, /*convertInt=*/ true, @@ -3420,6 +3425,22 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { Ty = Context.LongTy; else if (AllowUnsigned) Ty = Context.UnsignedLongTy; + // Check according to the rules of C90 6.1.3.2p5. C++03 [lex.icon]p2 + // is compatible. + else if (!getLangOpts().C99 && !getLangOpts().CPlusPlus11) { + const unsigned LongLongSize = + Context.getTargetInfo().getLongLongWidth(); + Diag(Tok.getLocation(), + getLangOpts().CPlusPlus + ? Literal.isLong + ? diag::warn_old_implicitly_unsigned_long_cxx + : /*C++98 UB*/ diag:: + ext_old_implicitly_unsigned_long_cxx + : diag::warn_old_implicitly_unsigned_long) + << (LongLongSize > LongSize ? /*will have type 'long long'*/ 0 + : /*will be ill-formed*/ 1); + Ty = Context.UnsignedLongTy; + } Width = LongSize; } } diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaLookup.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaLookup.cpp index c745b13..d0a55b5 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaLookup.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaLookup.cpp @@ -1180,6 +1180,16 @@ Module *Sema::getOwningModule(Decl *Entity) { assert(!Entity->isFromASTFile() && "hidden entity from AST file has no owning module"); + if (!getLangOpts().ModulesLocalVisibility) { + // If we're not tracking visibility locally, the only way a declaration + // can be hidden and local is if it's hidden because it's parent is (for + // instance, maybe this is a lazily-declared special member of an imported + // class). + auto *Parent = cast<NamedDecl>(Entity->getDeclContext()); + assert(Parent->isHidden() && "unexpectedly hidden decl"); + return getOwningModule(Parent); + } + // It's local and hidden; grab or compute its owning module. M = Entity->getLocalOwningModule(); if (M) @@ -1218,9 +1228,11 @@ Module *Sema::getOwningModule(Decl *Entity) { } void Sema::makeMergedDefinitionVisible(NamedDecl *ND, SourceLocation Loc) { - auto *M = PP.getModuleContainingLocation(Loc); - assert(M && "hidden definition not in any module"); - Context.mergeDefinitionIntoModule(ND, M); + if (auto *M = PP.getModuleContainingLocation(Loc)) + Context.mergeDefinitionIntoModule(ND, M); + else + // We're not building a module; just make the definition visible. + ND->setHidden(false); } /// \brief Find the module in which the given declaration was defined. @@ -3062,7 +3074,7 @@ class ShadowContextRAII { public: ShadowContextRAII(VisibleDeclsRecord &Visible) : Visible(Visible) { - Visible.ShadowMaps.push_back(ShadowMap()); + Visible.ShadowMaps.emplace_back(); } ~ShadowContextRAII() { diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaStmtAsm.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaStmtAsm.cpp index 9f48616..d19d881 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaStmtAsm.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaStmtAsm.cpp @@ -154,6 +154,14 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, if (CheckNakedParmReference(OutputExpr, *this)) return StmtError(); + // Bitfield can't be referenced with a pointer. + if (Info.allowsMemory() && OutputExpr->refersToBitField()) + return StmtError(Diag(OutputExpr->getLocStart(), + diag::err_asm_bitfield_in_memory_constraint) + << 1 + << Info.getConstraintStr() + << OutputExpr->getSourceRange()); + OutputConstraintInfos.push_back(Info); // If this is dependent, just continue. @@ -230,6 +238,14 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, if (CheckNakedParmReference(InputExpr, *this)) return StmtError(); + // Bitfield can't be referenced with a pointer. + if (Info.allowsMemory() && InputExpr->refersToBitField()) + return StmtError(Diag(InputExpr->getLocStart(), + diag::err_asm_bitfield_in_memory_constraint) + << 0 + << Info.getConstraintStr() + << InputExpr->getSourceRange()); + // Only allow void types for memory constraints. if (Info.allowsMemory() && !Info.allowsRegister()) { if (CheckAsmLValue(InputExpr, *this)) diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp index 37eeee2..19c0f2a 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp @@ -7369,12 +7369,23 @@ Sema::ActOnExplicitInstantiation(Scope *S, // FIXME: Need to notify the ASTMutationListener that we did this. Def->setTemplateSpecializationKind(TSK); - if (!getDLLAttr(Def) && getDLLAttr(Specialization)) { + if (!getDLLAttr(Def) && getDLLAttr(Specialization) && + Context.getTargetInfo().getCXXABI().isMicrosoft()) { + // In the MS ABI, an explicit instantiation definition can add a dll + // attribute to a template with a previous instantiation declaration. + // MinGW doesn't allow this. auto *A = cast<InheritableAttr>( getDLLAttr(Specialization)->clone(getASTContext())); A->setInherited(true); Def->addAttr(A); checkClassLevelDLLAttribute(Def); + + // Propagate attribute to base class templates. + for (auto &B : Def->bases()) { + if (auto *BT = dyn_cast_or_null<ClassTemplateSpecializationDecl>( + B.getType()->getAsCXXRecordDecl())) + propagateDLLAttrToBaseClassTemplate(Def, A, BT, B.getLocStart()); + } } } diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaType.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaType.cpp index 57a4689..628eb73 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaType.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaType.cpp @@ -2842,14 +2842,14 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, if ((T.getCVRQualifiers() || T->isAtomicType()) && !(S.getLangOpts().CPlusPlus && (T->isDependentType() || T->isRecordType()))) { - if (T->isVoidType() && !S.getLangOpts().CPlusPlus && - D.getFunctionDefinitionKind() == FDK_Definition) { - // [6.9.1/3] qualified void return is invalid on a C - // function definition. Apparently ok on declarations and - // in C++ though (!) - S.Diag(DeclType.Loc, diag::err_func_returning_qualified_void) << T; - } else - diagnoseRedundantReturnTypeQualifiers(S, T, D, chunkIndex); + if (T->isVoidType() && !S.getLangOpts().CPlusPlus && + D.getFunctionDefinitionKind() == FDK_Definition) { + // [6.9.1/3] qualified void return is invalid on a C + // function definition. Apparently ok on declarations and + // in C++ though (!) + S.Diag(DeclType.Loc, diag::err_func_returning_qualified_void) << T; + } else + diagnoseRedundantReturnTypeQualifiers(S, T, D, chunkIndex); } // Objective-C ARC ownership qualifiers are ignored on the function @@ -3500,16 +3500,27 @@ static AttributeList::Kind getAttrListKind(AttributedType::Kind kind) { } static void fillAttributedTypeLoc(AttributedTypeLoc TL, - const AttributeList *attrs) { - AttributedType::Kind kind = TL.getAttrKind(); - - assert(attrs && "no type attributes in the expected location!"); - AttributeList::Kind parsedKind = getAttrListKind(kind); - while (attrs->getKind() != parsedKind) { + const AttributeList *attrs, + const AttributeList *DeclAttrs = nullptr) { + // DeclAttrs and attrs cannot be both empty. + assert((attrs || DeclAttrs) && + "no type attributes in the expected location!"); + + AttributeList::Kind parsedKind = getAttrListKind(TL.getAttrKind()); + // Try to search for an attribute of matching kind in attrs list. + while (attrs && attrs->getKind() != parsedKind) attrs = attrs->getNext(); - assert(attrs && "no matching attribute in expected location!"); + if (!attrs) { + // No matching type attribute in attrs list found. + // Try searching through C++11 attributes in the declarator attribute list. + while (DeclAttrs && (!DeclAttrs->isCXX11Attribute() || + DeclAttrs->getKind() != parsedKind)) + DeclAttrs = DeclAttrs->getNext(); + attrs = DeclAttrs; } + assert(attrs && "no matching type attribute in expected location!"); + TL.setAttrNameLoc(attrs->getLoc()); if (TL.hasAttrExprOperand()) { assert(attrs->isArgExpr(0) && "mismatched attribute operand kind"); @@ -3863,6 +3874,7 @@ Sema::GetTypeSourceInfoForDeclarator(Declarator &D, QualType T, TypeSourceInfo *ReturnTypeInfo) { TypeSourceInfo *TInfo = Context.CreateTypeSourceInfo(T); UnqualTypeLoc CurrTL = TInfo->getTypeLoc().getUnqualifiedLoc(); + const AttributeList *DeclAttrs = D.getAttributes(); // Handle parameter packs whose type is a pack expansion. if (isa<PackExpansionType>(T)) { @@ -3879,7 +3891,7 @@ Sema::GetTypeSourceInfoForDeclarator(Declarator &D, QualType T, } while (AttributedTypeLoc TL = CurrTL.getAs<AttributedTypeLoc>()) { - fillAttributedTypeLoc(TL, D.getTypeObject(i).getAttrs()); + fillAttributedTypeLoc(TL, D.getTypeObject(i).getAttrs(), DeclAttrs); CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc(); } |