From 6eea8b8c1aad853d6161709d8b3035dfd867fa1c Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Fri, 16 Feb 2018 19:10:26 +0000 Subject: Vendor import of clang release_60 branch r325330: https://llvm.org/svn/llvm-project/cfe/branches/release_60@325330 --- docs/ReleaseNotes.rst | 5 ++ include/clang/AST/DeclBase.h | 4 + lib/AST/ASTContext.cpp | 2 +- lib/AST/DeclBase.cpp | 13 +++ lib/AST/MicrosoftMangle.cpp | 6 +- lib/CodeGen/CodeGenModule.cpp | 18 +--- lib/CodeGen/ItaniumCXXABI.cpp | 5 ++ lib/CodeGen/TargetInfo.cpp | 12 ++- lib/Format/TokenAnnotator.cpp | 21 +++-- lib/Format/UnwrappedLineParser.cpp | 60 ++++++++----- lib/Format/UnwrappedLineParser.h | 21 ++++- lib/Headers/avx512bwintrin.h | 6 +- lib/Headers/avx512fintrin.h | 2 +- lib/Lex/LiteralSupport.cpp | 24 +++-- lib/Sema/SemaChecking.cpp | 10 +++ lib/Sema/SemaDecl.cpp | 10 +++ lib/Sema/SemaInit.cpp | 49 +++++++--- test/CodeGen/avx512bw-builtins.c | 22 ++--- test/CodeGen/avx512f-builtins.c | 13 +-- test/CodeGen/ms_abi.c | 13 +++ test/CodeGenCXX/dllimport-missing-key.cpp | 20 +++++ test/CodeGenCXX/dllimport-rtti.cpp | 2 +- test/CodeGenCXX/microsoft-abi-emit-dependent.cpp | 11 +++ test/CodeGenCXX/msabi-swiftcall-cc.cpp | 28 ++++++ test/Lexer/cxx1y_digit_separators.cpp | 2 + test/Sema/bitfield.c | 4 + test/Sema/compare.c | 13 +++ test/Sema/cxx-as-c.c | 9 ++ test/SemaCXX/init-expr-crash.cpp | 8 ++ test/SemaCXX/type-traits.cpp | 1 + test/SemaTemplate/instantiate-init.cpp | 14 +++ unittests/Format/FormatTest.cpp | 108 +++++++++++++++++++---- 32 files changed, 412 insertions(+), 124 deletions(-) create mode 100644 test/CodeGenCXX/dllimport-missing-key.cpp create mode 100644 test/CodeGenCXX/microsoft-abi-emit-dependent.cpp create mode 100644 test/CodeGenCXX/msabi-swiftcall-cc.cpp create mode 100644 test/Sema/cxx-as-c.c diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index c5e037d0cd9d..be33f15cb229 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -132,6 +132,11 @@ New Compiler Flags difference between the ``-std=c17`` and ``-std=c11`` language modes is the value of the ``__STDC_VERSION__`` macro, as C17 is a bug fix release. +- Added the ``-fexperimental-isel`` and ``-fno-experimental-isel`` flags to + enable/disable the new GlobalISel instruction selection framework. This + feature is enabled by default for AArch64 at the ``-O0`` optimization level. + Support for other targets or optimization levels is currently incomplete. + Deprecated Compiler Flags ------------------------- diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index f93c9f0b9aaa..15de482a8619 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -836,6 +836,10 @@ public: void setLexicalDeclContext(DeclContext *DC); + /// Determine whether this declaration is a templated entity (whether it is + // within the scope of a template parameter). + bool isTemplated() const; + /// isDefinedOutsideFunctionOrMethod - This predicate returns true if this /// scoped decl is defined outside the current function or method. This is /// roughly global variables and functions, but also handles enums (which diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 3dc961d4f12b..c73ae9efe170 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -2145,7 +2145,7 @@ static bool unionHasUniqueObjectRepresentations(const ASTContext &Context, if (FieldSize != UnionSize) return false; } - return true; + return !RD->field_empty(); } static bool isStructEmpty(QualType Ty) { diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index 2cdcdae9ab02..d427c79c44ab 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -236,10 +236,23 @@ TemplateDecl *Decl::getDescribedTemplate() const { return RD->getDescribedClassTemplate(); else if (auto *VD = dyn_cast(this)) return VD->getDescribedVarTemplate(); + else if (auto *AD = dyn_cast(this)) + return AD->getDescribedAliasTemplate(); return nullptr; } +bool Decl::isTemplated() const { + // A declaration is dependent if it is a template or a template pattern, or + // is within (lexcially for a friend, semantically otherwise) a dependent + // context. + // FIXME: Should local extern declarations be treated like friends? + if (auto *AsDC = dyn_cast(this)) + return AsDC->isDependentContext(); + auto *DC = getFriendObjectKind() ? getLexicalDeclContext() : getDeclContext(); + return DC->isDependentContext() || isTemplateDecl() || getDescribedTemplate(); +} + const DeclContext *Decl::getParentFunctionOrMethod() const { for (const DeclContext *DC = getDeclContext(); DC && !DC->isTranslationUnit() && !DC->isNamespace(); diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp index 0c55c1a92287..b4e7a82eb000 100644 --- a/lib/AST/MicrosoftMangle.cpp +++ b/lib/AST/MicrosoftMangle.cpp @@ -950,11 +950,10 @@ void MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, } } +// ::= [] +// ::= [] void MicrosoftCXXNameMangler::mangleNestedName(const NamedDecl *ND) { - // ::= [] - // ::= [] const DeclContext *DC = getEffectiveDeclContext(ND); - while (!DC->isTranslationUnit()) { if (isa(ND) || isa(ND)) { unsigned Disc; @@ -2140,6 +2139,7 @@ void MicrosoftCXXNameMangler::mangleCallingConvention(CallingConv CC) { case CC_X86StdCall: Out << 'G'; break; case CC_X86FastCall: Out << 'I'; break; case CC_X86VectorCall: Out << 'Q'; break; + case CC_Swift: Out << 'S'; break; case CC_X86RegCall: Out << 'w'; break; } } diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index df33fc3e8200..2172486682cf 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -4000,18 +4000,13 @@ void CodeGenModule::EmitDeclContext(const DeclContext *DC) { /// EmitTopLevelDecl - Emit code for a single top level declaration. void CodeGenModule::EmitTopLevelDecl(Decl *D) { // Ignore dependent declarations. - if (D->getDeclContext() && D->getDeclContext()->isDependentContext()) + if (D->isTemplated()) return; switch (D->getKind()) { case Decl::CXXConversion: case Decl::CXXMethod: case Decl::Function: - // Skip function templates - if (cast(D)->getDescribedFunctionTemplate() || - cast(D)->isLateTemplateParsed()) - return; - EmitGlobal(cast(D)); // Always provide some coverage mapping // even for the functions that aren't emitted. @@ -4024,10 +4019,6 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { case Decl::Var: case Decl::Decomposition: - // Skip variable templates - if (cast(D)->getDescribedVarTemplate()) - return; - LLVM_FALLTHROUGH; case Decl::VarTemplateSpecialization: EmitGlobal(cast(D)); if (auto *DD = dyn_cast(D)) @@ -4086,16 +4077,9 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { DI->EmitUsingDirective(cast(*D)); return; case Decl::CXXConstructor: - // Skip function templates - if (cast(D)->getDescribedFunctionTemplate() || - cast(D)->isLateTemplateParsed()) - return; - getCXXABI().EmitCXXConstructors(cast(D)); break; case Decl::CXXDestructor: - if (cast(D)->isLateTemplateParsed()) - return; getCXXABI().EmitCXXDestructors(cast(D)); break; diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp index c375b82ea936..a3c2766dbb49 100644 --- a/lib/CodeGen/ItaniumCXXABI.cpp +++ b/lib/CodeGen/ItaniumCXXABI.cpp @@ -2761,6 +2761,11 @@ static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM, // N.B. We must always emit the RTTI data ourselves if there exists a key // function. bool IsDLLImport = RD->hasAttr(); + + // Don't import the RTTI but emit it locally. + if (CGM.getTriple().isWindowsGNUEnvironment() && IsDLLImport) + return false; + if (CGM.getVTables().isVTableExternal(RD)) return IsDLLImport && !CGM.getTriple().isWindowsItaniumEnvironment() ? false diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index 4b8006428f8f..abd633280b9d 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -3543,7 +3543,17 @@ ABIArgInfo X86_64ABIInfo::classifyRegCallStructType(QualType Ty, void X86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const { - bool IsRegCall = FI.getCallingConvention() == llvm::CallingConv::X86_RegCall; + const unsigned CallingConv = FI.getCallingConvention(); + // It is possible to force Win64 calling convention on any x86_64 target by + // using __attribute__((ms_abi)). In such case to correctly emit Win64 + // compatible code delegate this call to WinX86_64ABIInfo::computeInfo. + if (CallingConv == llvm::CallingConv::Win64) { + WinX86_64ABIInfo Win64ABIInfo(CGT); + Win64ABIInfo.computeInfo(FI); + return; + } + + bool IsRegCall = CallingConv == llvm::CallingConv::X86_RegCall; // Keep track of the number of assigned registers. unsigned FreeIntRegs = IsRegCall ? 11 : 6; diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp index 298c72b002f8..079b330f3a7d 100644 --- a/lib/Format/TokenAnnotator.cpp +++ b/lib/Format/TokenAnnotator.cpp @@ -1723,15 +1723,18 @@ void TokenAnnotator::setCommentLineLevels( } } - if (NextNonCommentLine && CommentLine) { - // If the comment is currently aligned with the line immediately following - // it, that's probably intentional and we should keep it. - bool AlignedWithNextLine = - NextNonCommentLine->First->NewlinesBefore <= 1 && - NextNonCommentLine->First->OriginalColumn == - (*I)->First->OriginalColumn; - if (AlignedWithNextLine) - (*I)->Level = NextNonCommentLine->Level; + // If the comment is currently aligned with the line immediately following + // it, that's probably intentional and we should keep it. + if (NextNonCommentLine && CommentLine && + NextNonCommentLine->First->NewlinesBefore <= 1 && + NextNonCommentLine->First->OriginalColumn == + (*I)->First->OriginalColumn) { + // Align comments for preprocessor lines with the # in column 0. + // Otherwise, align with the next line. + (*I)->Level = (NextNonCommentLine->Type == LT_PreprocessorDirective || + NextNonCommentLine->Type == LT_ImportStatement) + ? 0 + : NextNonCommentLine->Level; } else { NextNonCommentLine = (*I)->First->isNot(tok::r_brace) ? (*I) : nullptr; } diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp index b8608dcac9c7..34d4ce28aad1 100644 --- a/lib/Format/UnwrappedLineParser.cpp +++ b/lib/Format/UnwrappedLineParser.cpp @@ -234,14 +234,17 @@ UnwrappedLineParser::UnwrappedLineParser(const FormatStyle &Style, CurrentLines(&Lines), Style(Style), Keywords(Keywords), CommentPragmasRegex(Style.CommentPragmas), Tokens(nullptr), Callback(Callback), AllTokens(Tokens), PPBranchLevel(-1), - IfNdefCondition(nullptr), FoundIncludeGuardStart(false), - IncludeGuardRejected(false), FirstStartColumn(FirstStartColumn) {} + IncludeGuard(Style.IndentPPDirectives == FormatStyle::PPDIS_None + ? IG_Rejected + : IG_Inited), + IncludeGuardToken(nullptr), FirstStartColumn(FirstStartColumn) {} void UnwrappedLineParser::reset() { PPBranchLevel = -1; - IfNdefCondition = nullptr; - FoundIncludeGuardStart = false; - IncludeGuardRejected = false; + IncludeGuard = Style.IndentPPDirectives == FormatStyle::PPDIS_None + ? IG_Rejected + : IG_Inited; + IncludeGuardToken = nullptr; Line.reset(new UnwrappedLine); CommentsBeforeNextToken.clear(); FormatTok = nullptr; @@ -264,6 +267,14 @@ void UnwrappedLineParser::parse() { readToken(); parseFile(); + + // If we found an include guard then all preprocessor directives (other than + // the guard) are over-indented by one. + if (IncludeGuard == IG_Found) + for (auto &Line : Lines) + if (Line.InPPDirective && Line.Level > 0) + --Line.Level; + // Create line with eof token. pushToken(FormatTok); addUnwrappedLine(); @@ -712,26 +723,27 @@ void UnwrappedLineParser::parsePPIf(bool IfDef) { // If there's a #ifndef on the first line, and the only lines before it are // comments, it could be an include guard. bool MaybeIncludeGuard = IfNDef; - if (!IncludeGuardRejected && !FoundIncludeGuardStart && MaybeIncludeGuard) { + if (IncludeGuard == IG_Inited && MaybeIncludeGuard) for (auto &Line : Lines) { if (!Line.Tokens.front().Tok->is(tok::comment)) { MaybeIncludeGuard = false; - IncludeGuardRejected = true; + IncludeGuard = IG_Rejected; break; } } - } --PPBranchLevel; parsePPUnknown(); ++PPBranchLevel; - if (!IncludeGuardRejected && !FoundIncludeGuardStart && MaybeIncludeGuard) - IfNdefCondition = IfCondition; + if (IncludeGuard == IG_Inited && MaybeIncludeGuard) { + IncludeGuard = IG_IfNdefed; + IncludeGuardToken = IfCondition; + } } void UnwrappedLineParser::parsePPElse() { // If a potential include guard has an #else, it's not an include guard. - if (FoundIncludeGuardStart && PPBranchLevel == 0) - FoundIncludeGuardStart = false; + if (IncludeGuard == IG_Defined && PPBranchLevel == 0) + IncludeGuard = IG_Rejected; conditionalCompilationAlternative(); if (PPBranchLevel > -1) --PPBranchLevel; @@ -745,34 +757,37 @@ void UnwrappedLineParser::parsePPEndIf() { conditionalCompilationEnd(); parsePPUnknown(); // If the #endif of a potential include guard is the last thing in the file, - // then we count it as a real include guard and subtract one from every - // preprocessor indent. + // then we found an include guard. unsigned TokenPosition = Tokens->getPosition(); FormatToken *PeekNext = AllTokens[TokenPosition]; - if (FoundIncludeGuardStart && PPBranchLevel == -1 && PeekNext->is(tok::eof) && + if (IncludeGuard == IG_Defined && PPBranchLevel == -1 && + PeekNext->is(tok::eof) && Style.IndentPPDirectives != FormatStyle::PPDIS_None) - for (auto &Line : Lines) - if (Line.InPPDirective && Line.Level > 0) - --Line.Level; + IncludeGuard = IG_Found; } void UnwrappedLineParser::parsePPDefine() { nextToken(); if (FormatTok->Tok.getKind() != tok::identifier) { + IncludeGuard = IG_Rejected; + IncludeGuardToken = nullptr; parsePPUnknown(); return; } - if (IfNdefCondition && IfNdefCondition->TokenText == FormatTok->TokenText) { - FoundIncludeGuardStart = true; + + if (IncludeGuard == IG_IfNdefed && + IncludeGuardToken->TokenText == FormatTok->TokenText) { + IncludeGuard = IG_Defined; + IncludeGuardToken = nullptr; for (auto &Line : Lines) { if (!Line.Tokens.front().Tok->isOneOf(tok::comment, tok::hash)) { - FoundIncludeGuardStart = false; + IncludeGuard = IG_Rejected; break; } } } - IfNdefCondition = nullptr; + nextToken(); if (FormatTok->Tok.getKind() == tok::l_paren && FormatTok->WhitespaceRange.getBegin() == @@ -799,7 +814,6 @@ void UnwrappedLineParser::parsePPUnknown() { if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash) Line->Level += PPBranchLevel + 1; addUnwrappedLine(); - IfNdefCondition = nullptr; } // Here we blacklist certain tokens that are not usually the first token in an diff --git a/lib/Format/UnwrappedLineParser.h b/lib/Format/UnwrappedLineParser.h index 1d8ccabbd0f8..cee03e9bce33 100644 --- a/lib/Format/UnwrappedLineParser.h +++ b/lib/Format/UnwrappedLineParser.h @@ -248,10 +248,23 @@ private: // sequence. std::stack PPChainBranchIndex; - // Contains the #ifndef condition for a potential include guard. - FormatToken *IfNdefCondition; - bool FoundIncludeGuardStart; - bool IncludeGuardRejected; + // Include guard search state. Used to fixup preprocessor indent levels + // so that include guards do not participate in indentation. + enum IncludeGuardState { + IG_Inited, // Search started, looking for #ifndef. + IG_IfNdefed, // #ifndef found, IncludeGuardToken points to condition. + IG_Defined, // Matching #define found, checking other requirements. + IG_Found, // All requirements met, need to fix indents. + IG_Rejected, // Search failed or never started. + }; + + // Current state of include guard search. + IncludeGuardState IncludeGuard; + + // Points to the #ifndef condition for a potential include guard. Null unless + // IncludeGuardState == IG_IfNdefed. + FormatToken *IncludeGuardToken; + // Contains the first start column where the source begins. This is zero for // normal source code and may be nonzero when formatting a code fragment that // does not start at the beginning of the file. diff --git a/lib/Headers/avx512bwintrin.h b/lib/Headers/avx512bwintrin.h index 3ff0e3aafdcc..064300a48798 100644 --- a/lib/Headers/avx512bwintrin.h +++ b/lib/Headers/avx512bwintrin.h @@ -1854,13 +1854,15 @@ _mm512_maskz_set1_epi8 (__mmask64 __M, char __A) static __inline__ __mmask64 __DEFAULT_FN_ATTRS _mm512_kunpackd (__mmask64 __A, __mmask64 __B) { - return (__mmask64) (( __A & 0xFFFFFFFF) | ( __B << 32)); + return (__mmask64) __builtin_ia32_kunpckdi ((__mmask64) __A, + (__mmask64) __B); } static __inline__ __mmask32 __DEFAULT_FN_ATTRS _mm512_kunpackw (__mmask32 __A, __mmask32 __B) { -return (__mmask32) (( __A & 0xFFFF) | ( __B << 16)); + return (__mmask32) __builtin_ia32_kunpcksi ((__mmask32) __A, + (__mmask32) __B); } static __inline__ __m512i __DEFAULT_FN_ATTRS diff --git a/lib/Headers/avx512fintrin.h b/lib/Headers/avx512fintrin.h index d34f0b1327ae..f5137428ba3f 100644 --- a/lib/Headers/avx512fintrin.h +++ b/lib/Headers/avx512fintrin.h @@ -8787,7 +8787,7 @@ _mm512_kortestz (__mmask16 __A, __mmask16 __B) static __inline__ __mmask16 __DEFAULT_FN_ATTRS _mm512_kunpackb (__mmask16 __A, __mmask16 __B) { - return (__mmask16) (( __A & 0xFF) | ( __B << 8)); + return (__mmask16) __builtin_ia32_kunpckhi ((__mmask16) __A, (__mmask16) __B); } static __inline__ __mmask16 __DEFAULT_FN_ATTRS diff --git a/lib/Lex/LiteralSupport.cpp b/lib/Lex/LiteralSupport.cpp index cbec5e6b6385..ec342ee3ae2a 100644 --- a/lib/Lex/LiteralSupport.cpp +++ b/lib/Lex/LiteralSupport.cpp @@ -738,15 +738,17 @@ void NumericLiteralParser::ParseDecimalOrOctalCommon(SourceLocation TokLoc){ s++; radix = 10; saw_exponent = true; - if (*s == '+' || *s == '-') s++; // sign + if (s != ThisTokEnd && (*s == '+' || *s == '-')) s++; // sign const char *first_non_digit = SkipDigits(s); if (containsDigits(s, first_non_digit)) { checkSeparator(TokLoc, s, CSK_BeforeDigits); s = first_non_digit; } else { - PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, Exponent-ThisTokBegin), - diag::err_exponent_has_no_digits); - hadError = true; + if (!hadError) { + PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, Exponent-ThisTokBegin), + diag::err_exponent_has_no_digits); + hadError = true; + } return; } } @@ -787,10 +789,12 @@ void NumericLiteralParser::checkSeparator(SourceLocation TokLoc, } else if (Pos == ThisTokEnd) return; - if (isDigitSeparator(*Pos)) + if (isDigitSeparator(*Pos)) { PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, Pos - ThisTokBegin), diag::err_digit_separator_not_between_digits) << IsAfterDigits; + hadError = true; + } } /// ParseNumberStartingWithZero - This method is called when the first character @@ -840,12 +844,14 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) { const char *Exponent = s; s++; saw_exponent = true; - if (*s == '+' || *s == '-') s++; // sign + if (s != ThisTokEnd && (*s == '+' || *s == '-')) s++; // sign const char *first_non_digit = SkipDigits(s); if (!containsDigits(s, first_non_digit)) { - PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, Exponent-ThisTokBegin), - diag::err_exponent_has_no_digits); - hadError = true; + if (!hadError) { + PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, Exponent-ThisTokBegin), + diag::err_exponent_has_no_digits); + hadError = true; + } return; } checkSeparator(TokLoc, s, CSK_BeforeDigits); diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 803f87b3c568..57af6b86bf80 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -8972,6 +8972,16 @@ static void AnalyzeComparison(Sema &S, BinaryOperator *E) { LHS = LHS->IgnoreParenImpCasts(); RHS = RHS->IgnoreParenImpCasts(); + if (!S.getLangOpts().CPlusPlus) { + // Avoid warning about comparison of integers with different signs when + // RHS/LHS has a `typeof(E)` type whose sign is different from the sign of + // the type of `E`. + if (const auto *TET = dyn_cast(LHS->getType())) + LHS = TET->getUnderlyingExpr()->IgnoreParenImpCasts(); + if (const auto *TET = dyn_cast(RHS->getType())) + RHS = TET->getUnderlyingExpr()->IgnoreParenImpCasts(); + } + // Check to see if one of the (unmodified) operands is of different // signedness. Expr *signedOperand, *unsignedOperand; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 743f4bb5e822..7ca48c34e516 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -12507,10 +12507,20 @@ void Sema::ActOnFinishDelayedAttribute(Scope *S, Decl *D, /// call, forming a call to an implicitly defined function (per C99 6.5.1p2). NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, IdentifierInfo &II, Scope *S) { + // Find the scope in which the identifier is injected and the corresponding + // DeclContext. + // FIXME: C89 does not say what happens if there is no enclosing block scope. + // In that case, we inject the declaration into the translation unit scope + // instead. Scope *BlockScope = S; while (!BlockScope->isCompoundStmtScope() && BlockScope->getParent()) BlockScope = BlockScope->getParent(); + Scope *ContextScope = BlockScope; + while (!ContextScope->getEntity()) + ContextScope = ContextScope->getParent(); + ContextRAII SavedContext(*this, ContextScope->getEntity()); + // Before we produce a declaration for an implicitly defined // function, see whether there was a locally-scoped declaration of // this name as a function or variable. If so, use that diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 011051da58e5..df64a33954fa 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -352,6 +352,7 @@ class InitListChecker { bool FillWithNoInit = false); void FillInEmptyInitializations(const InitializedEntity &Entity, InitListExpr *ILE, bool &RequiresSecondPass, + InitListExpr *OuterILE, unsigned OuterIndex, bool FillWithNoInit = false); bool CheckFlexibleArrayInit(const InitializedEntity &Entity, Expr *InitExpr, FieldDecl *Field, @@ -517,12 +518,13 @@ void InitListChecker::FillInEmptyInitForBase( ILE->setInit(Init, BaseInit.getAs()); } else if (InitListExpr *InnerILE = dyn_cast(ILE->getInit(Init))) { - FillInEmptyInitializations(BaseEntity, InnerILE, - RequiresSecondPass, FillWithNoInit); + FillInEmptyInitializations(BaseEntity, InnerILE, RequiresSecondPass, + ILE, Init, FillWithNoInit); } else if (DesignatedInitUpdateExpr *InnerDIUE = dyn_cast(ILE->getInit(Init))) { FillInEmptyInitializations(BaseEntity, InnerDIUE->getUpdater(), - RequiresSecondPass, /*FillWithNoInit =*/true); + RequiresSecondPass, ILE, Init, + /*FillWithNoInit =*/true); } } @@ -605,24 +607,43 @@ void InitListChecker::FillInEmptyInitForField(unsigned Init, FieldDecl *Field, } else if (InitListExpr *InnerILE = dyn_cast(ILE->getInit(Init))) FillInEmptyInitializations(MemberEntity, InnerILE, - RequiresSecondPass, FillWithNoInit); + RequiresSecondPass, ILE, Init, FillWithNoInit); else if (DesignatedInitUpdateExpr *InnerDIUE = dyn_cast(ILE->getInit(Init))) FillInEmptyInitializations(MemberEntity, InnerDIUE->getUpdater(), - RequiresSecondPass, /*FillWithNoInit =*/ true); + RequiresSecondPass, ILE, Init, + /*FillWithNoInit =*/true); } /// Recursively replaces NULL values within the given initializer list /// with expressions that perform value-initialization of the -/// appropriate type. +/// appropriate type, and finish off the InitListExpr formation. void InitListChecker::FillInEmptyInitializations(const InitializedEntity &Entity, InitListExpr *ILE, bool &RequiresSecondPass, + InitListExpr *OuterILE, + unsigned OuterIndex, bool FillWithNoInit) { assert((ILE->getType() != SemaRef.Context.VoidTy) && "Should not have void type"); + // If this is a nested initializer list, we might have changed its contents + // (and therefore some of its properties, such as instantiation-dependence) + // while filling it in. Inform the outer initializer list so that its state + // can be updated to match. + // FIXME: We should fully build the inner initializers before constructing + // the outer InitListExpr instead of mutating AST nodes after they have + // been used as subexpressions of other nodes. + struct UpdateOuterILEWithUpdatedInit { + InitListExpr *Outer; + unsigned OuterIndex; + ~UpdateOuterILEWithUpdatedInit() { + if (Outer) + Outer->setInit(OuterIndex, Outer->getInit(OuterIndex)); + } + } UpdateOuterRAII = {OuterILE, OuterIndex}; + // A transparent ILE is not performing aggregate initialization and should // not be filled in. if (ILE->isTransparent()) @@ -769,11 +790,12 @@ InitListChecker::FillInEmptyInitializations(const InitializedEntity &Entity, } else if (InitListExpr *InnerILE = dyn_cast_or_null(InitExpr)) FillInEmptyInitializations(ElementEntity, InnerILE, RequiresSecondPass, - FillWithNoInit); + ILE, Init, FillWithNoInit); else if (DesignatedInitUpdateExpr *InnerDIUE = dyn_cast_or_null(InitExpr)) FillInEmptyInitializations(ElementEntity, InnerDIUE->getUpdater(), - RequiresSecondPass, /*FillWithNoInit =*/ true); + RequiresSecondPass, ILE, Init, + /*FillWithNoInit =*/true); } } @@ -795,10 +817,11 @@ InitListChecker::InitListChecker(Sema &S, const InitializedEntity &Entity, if (!hadError && !VerifyOnly) { bool RequiresSecondPass = false; - FillInEmptyInitializations(Entity, FullyStructuredList, RequiresSecondPass); + FillInEmptyInitializations(Entity, FullyStructuredList, RequiresSecondPass, + /*OuterILE=*/nullptr, /*OuterIndex=*/0); if (RequiresSecondPass && !hadError) FillInEmptyInitializations(Entity, FullyStructuredList, - RequiresSecondPass); + RequiresSecondPass, nullptr, 0); } } @@ -1162,10 +1185,12 @@ void InitListChecker::CheckSubElementType(const InitializedEntity &Entity, if (!hadError && !VerifyOnly) { bool RequiresSecondPass = false; FillInEmptyInitializations(Entity, InnerStructuredList, - RequiresSecondPass); + RequiresSecondPass, StructuredList, + StructuredIndex); if (RequiresSecondPass && !hadError) FillInEmptyInitializations(Entity, InnerStructuredList, - RequiresSecondPass); + RequiresSecondPass, StructuredList, + StructuredIndex); } ++StructuredIndex; ++Index; diff --git a/test/CodeGen/avx512bw-builtins.c b/test/CodeGen/avx512bw-builtins.c index 3160a6667c00..190387b2d97a 100644 --- a/test/CodeGen/avx512bw-builtins.c +++ b/test/CodeGen/avx512bw-builtins.c @@ -1626,26 +1626,16 @@ __m512i test_mm512_maskz_set1_epi8(__mmask64 __M, char __A) { return _mm512_maskz_set1_epi8(__M, __A); } -__mmask64 test_mm512_kunpackd(__m512i __A, __m512i __B, __m512i __C, __m512i __D, __m512i __E, __m512i __F) { +__mmask64 test_mm512_kunpackd(__mmask64 __A, __mmask64 __B) { // CHECK-LABEL: @test_mm512_kunpackd - // CHECK: bitcast <64 x i1> %{{.*}} to i64 - // CHECK: bitcast <64 x i1> %{{.*}} to i64 - // CHECK: and i64 %{{.*}}, 4294967295 - // CHECK: shl i64 %{{.*}}, 32 - // CHECK: or i64 %{{.*}}, %{{.*}} - // CHECK: bitcast i64 %{{.*}} to <64 x i1> - return _mm512_mask_cmpneq_epu8_mask(_mm512_kunpackd(_mm512_cmpneq_epu8_mask(__B, __A),_mm512_cmpneq_epu8_mask(__C, __D)), __E, __F); + // CHECK: @llvm.x86.avx512.kunpck.dq + return _mm512_kunpackd(__A, __B); } -__mmask32 test_mm512_kunpackw(__m512i __A, __m512i __B, __m512i __C, __m512i __D, __m512i __E, __m512i __F) { +__mmask32 test_mm512_kunpackw(__mmask32 __A, __mmask32 __B) { // CHECK-LABEL: @test_mm512_kunpackw - // CHECK: bitcast <32 x i1> %{{.*}} to i32 - // CHECK: bitcast <32 x i1> %{{.*}} to i32 - // CHECK: and i32 %{{.*}}, 65535 - // CHECK: shl i32 %{{.*}}, 16 - // CHECK: or i32 %{{.*}}, %{{.*}} - // CHECK: bitcast i32 %{{.*}} to <32 x i1> - return _mm512_mask_cmpneq_epu16_mask(_mm512_kunpackw(_mm512_cmpneq_epu16_mask(__B, __A),_mm512_cmpneq_epu16_mask(__C, __D)), __E, __F); + // CHECK: @llvm.x86.avx512.kunpck.wd + return _mm512_kunpackw(__A, __B); } __m512i test_mm512_mask_loadu_epi16(__m512i __W, __mmask32 __U, void const *__P) { diff --git a/test/CodeGen/avx512f-builtins.c b/test/CodeGen/avx512f-builtins.c index ce831d690ee7..2ba2faf1b697 100644 --- a/test/CodeGen/avx512f-builtins.c +++ b/test/CodeGen/avx512f-builtins.c @@ -6259,17 +6259,10 @@ int test_mm512_kortestz(__mmask16 __A, __mmask16 __B) { return _mm512_kortestz(__A, __B); } -__mmask16 test_mm512_kunpackb(__m512i __A, __m512i __B, __m512i __C, __m512i __D, __m512i __E, __m512i __F) { +__mmask16 test_mm512_kunpackb(__mmask16 __A, __mmask16 __B) { // CHECK-LABEL: @test_mm512_kunpackb - // CHECK: bitcast <16 x i1> %{{.*}} to i16 - // CHECK: bitcast <16 x i1> %{{.*}} to i16 - // CHECK: and i32 %{{.*}}, 255 - // CHECK: shl i32 %{{.*}}, 8 - // CHECK: or i32 %{{.*}}, %{{.*}} - // CHECK: bitcast i16 %{{.*}} to <16 x i1> - return _mm512_mask_cmpneq_epu32_mask(_mm512_kunpackb(_mm512_cmpneq_epu32_mask(__A, __B), - _mm512_cmpneq_epu32_mask(__C, __D)), - __E, __F); + // CHECK: @llvm.x86.avx512.kunpck.bw + return _mm512_kunpackb(__A, __B); } __mmask16 test_mm512_kxnor(__m512i __A, __m512i __B, __m512i __C, __m512i __D, __m512i __E, __m512i __F) { diff --git a/test/CodeGen/ms_abi.c b/test/CodeGen/ms_abi.c index 407087e40916..7486166c78d4 100644 --- a/test/CodeGen/ms_abi.c +++ b/test/CodeGen/ms_abi.c @@ -146,3 +146,16 @@ void __attribute__((sysv_abi)) f6(__builtin_ms_va_list ap) { // WIN64: %[[AP_VAL:.*]] = load i8*, i8** %[[AP]] // WIN64-NEXT: store i8* %[[AP_VAL]], i8** %[[AP2:.*]] } + +// This test checks if structs are passed according to Win64 calling convention +// when it's enforced by __attribute((ms_abi)). +struct i128 { + unsigned long long a; + unsigned long long b; +}; + +__attribute__((ms_abi)) struct i128 f7(struct i128 a) { + // WIN64: define void @f7(%struct.i128* noalias sret %agg.result, %struct.i128* %a) + // FREEBSD: define win64cc void @f7(%struct.i128* noalias sret %agg.result, %struct.i128* %a) + return a; +} diff --git a/test/CodeGenCXX/dllimport-missing-key.cpp b/test/CodeGenCXX/dllimport-missing-key.cpp new file mode 100644 index 000000000000..d8ef7aa7ea68 --- /dev/null +++ b/test/CodeGenCXX/dllimport-missing-key.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU %s + +class __declspec(dllimport) QObjectData { +public: + virtual ~QObjectData() = 0; + void *ptr; + + int method() const; +}; + +class LocalClass : public QObjectData { +}; + +void call() { + (new LocalClass())->method(); +} + +// GNU-DAG: @_ZTV11QObjectData = available_externally dllimport +// GNU-DAG: @_ZTS11QObjectData = linkonce_odr +// GNU-DAG: @_ZTI11QObjectData = linkonce_odr diff --git a/test/CodeGenCXX/dllimport-rtti.cpp b/test/CodeGenCXX/dllimport-rtti.cpp index 91e747ae1c15..dfb39a15eda5 100644 --- a/test/CodeGenCXX/dllimport-rtti.cpp +++ b/test/CodeGenCXX/dllimport-rtti.cpp @@ -12,7 +12,7 @@ struct __declspec(dllimport) S { // MSVC-DAG: @"\01??_R3S@@8" = linkonce_odr // GNU-DAG: @_ZTV1S = available_externally dllimport -// GNU-DAG: @_ZTI1S = external dllimport +// GNU-DAG: @_ZTI1S = linkonce_odr struct U : S { } u; diff --git a/test/CodeGenCXX/microsoft-abi-emit-dependent.cpp b/test/CodeGenCXX/microsoft-abi-emit-dependent.cpp new file mode 100644 index 000000000000..e74ebc879f5b --- /dev/null +++ b/test/CodeGenCXX/microsoft-abi-emit-dependent.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -emit-llvm-only -fmodules -triple x86_64-windows %s +// PR36181 +#pragma clang module build foo +module foo {} +#pragma clang module contents +template struct A { + friend void f(A) {} +}; +#pragma clang module endbuild +#pragma clang module import foo +void g() { f(A()); } diff --git a/test/CodeGenCXX/msabi-swiftcall-cc.cpp b/test/CodeGenCXX/msabi-swiftcall-cc.cpp new file mode 100644 index 000000000000..5a5453af8fa1 --- /dev/null +++ b/test/CodeGenCXX/msabi-swiftcall-cc.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -triple i686-unknown-windows-msvc -fdeclspec -emit-llvm %s -o - | FileCheck %s + +void __attribute__((__swiftcall__)) f() {} +// CHECK-DAG: @"\01?f@@YSXXZ" + +void (__attribute__((__swiftcall__)) *p)(); +// CHECK-DAG: @"\01?p@@3P6SXXZA" + +namespace { +void __attribute__((__swiftcall__)) __attribute__((__used__)) f() { } +// CHECK-DAG: "\01?f@?A@@YSXXZ" +} + +namespace n { +void __attribute__((__swiftcall__)) f() {} +// CHECK-DAG: "\01?f@n@@YSXXZ" +} + +struct __declspec(dllexport) S { + S(const S &) = delete; + S & operator=(const S &) = delete; + void __attribute__((__swiftcall__)) m() { } + // CHECK-DAG: "\01?m@S@@QASXXZ" +}; + +void f(void (__attribute__((__swiftcall__))())) {} +// CHECK-DAG: "\01?f@@YAXP6SXXZ@Z" + diff --git a/test/Lexer/cxx1y_digit_separators.cpp b/test/Lexer/cxx1y_digit_separators.cpp index 55366342eda0..67dcd7c510ed 100644 --- a/test/Lexer/cxx1y_digit_separators.cpp +++ b/test/Lexer/cxx1y_digit_separators.cpp @@ -51,6 +51,8 @@ namespace floating { float u = 0x.'p1f; // expected-error {{hexadecimal floating literal requires a significand}} float v = 0e'f; // expected-error {{exponent has no digits}} float w = 0x0p'f; // expected-error {{exponent has no digits}} + float x = 0'e+1; // expected-error {{digit separator cannot appear at end of digit sequence}} + float y = 0x0'p+1; // expected-error {{digit separator cannot appear at end of digit sequence}} } #line 123'456 diff --git a/test/Sema/bitfield.c b/test/Sema/bitfield.c index d625366e4e1f..13e9480a378b 100644 --- a/test/Sema/bitfield.c +++ b/test/Sema/bitfield.c @@ -82,3 +82,7 @@ typedef __typeof__(+(t5.n--)) Unsigned; // also act like compound-assignment. struct Test6 { : 0.0; // expected-error{{type name requires a specifier or qualifier}} }; + +struct PR36157 { + int n : 1 ? 1 : implicitly_declare_function(); // expected-warning {{invalid in C99}} +}; diff --git a/test/Sema/compare.c b/test/Sema/compare.c index 7cd8adab8921..b2b486f59f87 100644 --- a/test/Sema/compare.c +++ b/test/Sema/compare.c @@ -391,3 +391,16 @@ typedef char two_chars[2]; void test12(unsigned a) { if (0 && -1 > a) { } } + +// PR36008 + +enum PR36008EnumTest { + kPR36008Value = 0, +}; + +void pr36008(enum PR36008EnumTest lhs) { + __typeof__(lhs) x = lhs; + __typeof__(kPR36008Value) y = (kPR36008Value); + if (x == y) x = y; // no warning + if (y == x) y = x; // no warning +} diff --git a/test/Sema/cxx-as-c.c b/test/Sema/cxx-as-c.c new file mode 100644 index 000000000000..41d7350d1f15 --- /dev/null +++ b/test/Sema/cxx-as-c.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 %s -verify + +// PR36157 +struct Foo { + Foo(int n) : n_(n) {} // expected-error 1+{{}} expected-warning 1+{{}} +private: + int n; +}; +int main() { Foo f; } // expected-error 1+{{}} diff --git a/test/SemaCXX/init-expr-crash.cpp b/test/SemaCXX/init-expr-crash.cpp index 407da78e60b0..201ab03955cd 100644 --- a/test/SemaCXX/init-expr-crash.cpp +++ b/test/SemaCXX/init-expr-crash.cpp @@ -29,3 +29,11 @@ template struct B { return 0; } }; + +// This test checks for a crash that resulted from us miscomputing the +// dependence of a nested initializer list. +template struct X { + static constexpr int n = 4; + static constexpr int a[1][1] = {n}; +}; + diff --git a/test/SemaCXX/type-traits.cpp b/test/SemaCXX/type-traits.cpp index b334e507554f..3c2f9c7f0fb6 100644 --- a/test/SemaCXX/type-traits.cpp +++ b/test/SemaCXX/type-traits.cpp @@ -2524,6 +2524,7 @@ static_assert(!has_unique_object_representations::value, "No refere static_assert(!has_unique_object_representations::value, "No references!"); static_assert(!has_unique_object_representations::value, "No references!"); static_assert(!has_unique_object_representations::value, "No empty types!"); +static_assert(!has_unique_object_representations::value, "No empty types!"); class Compressed : Empty { int x; diff --git a/test/SemaTemplate/instantiate-init.cpp b/test/SemaTemplate/instantiate-init.cpp index 244e94f6d605..51fa6955d0c0 100644 --- a/test/SemaTemplate/instantiate-init.cpp +++ b/test/SemaTemplate/instantiate-init.cpp @@ -142,3 +142,17 @@ namespace ReturnStmtIsInitialization { template X f() { return {}; } auto &&x = f(); } + +namespace InitListUpdate { + struct A { int n; }; + using AA = A[1]; + + // Check that an init list update doesn't "lose" the pack-ness of an expression. + template void f() { + g(AA{0, [0].n = N} ...); // expected-warning 3{{overrides prior init}} expected-note 3{{previous init}} + g(AA{N, [0].n = 0} ...); // expected-warning 3{{overrides prior init}} expected-note 3{{previous init}} + }; + + void g(AA, AA); + void h() { f<1, 2>(); } // expected-note {{instantiation of}} +} diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index 2cae9dd0c547..593caf0fdc9a 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -2532,6 +2532,20 @@ TEST_F(FormatTest, IndentPreprocessorDirectives) { "#elif FOO\n" "#endif", Style); + // Non-identifier #define after potential include guard. + verifyFormat("#ifndef FOO\n" + "# define 1\n" + "#endif\n", + Style); + // #if closes past last non-preprocessor line. + verifyFormat("#ifndef FOO\n" + "#define FOO\n" + "#if 1\n" + "int i;\n" + "# define A 0\n" + "#endif\n" + "#endif\n", + Style); // FIXME: This doesn't handle the case where there's code between the // #ifndef and #define but all other conditions hold. This is because when // the #define line is parsed, UnwrappedLineParser::Lines doesn't hold the @@ -2580,21 +2594,85 @@ TEST_F(FormatTest, IndentPreprocessorDirectives) { "code();\n" "#endif", Style)); - // FIXME: The comment indent corrector in TokenAnnotator gets thrown off by - // preprocessor indentation. - EXPECT_EQ("#if 1\n" - " // comment\n" - "# define A 0\n" - "// comment\n" - "# define B 0\n" - "#endif", - format("#if 1\n" - "// comment\n" - "# define A 0\n" - " // comment\n" - "# define B 0\n" - "#endif", - Style)); + // Keep comments aligned with #, otherwise indent comments normally. These + // tests cannot use verifyFormat because messUp manipulates leading + // whitespace. + { + const char *Expected = "" + "void f() {\n" + "#if 1\n" + "// Preprocessor aligned.\n" + "# define A 0\n" + " // Code. Separated by blank line.\n" + "\n" + "# define B 0\n" + " // Code. Not aligned with #\n" + "# define C 0\n" + "#endif"; + const char *ToFormat = "" + "void f() {\n" + "#if 1\n" + "// Preprocessor aligned.\n" + "# define A 0\n" + "// Code. Separated by blank line.\n" + "\n" + "# define B 0\n" + " // Code. Not aligned with #\n" + "# define C 0\n" + "#endif"; + EXPECT_EQ(Expected, format(ToFormat, Style)); + EXPECT_EQ(Expected, format(Expected, Style)); + } + // Keep block quotes aligned. + { + const char *Expected = "" + "void f() {\n" + "#if 1\n" + "/* Preprocessor aligned. */\n" + "# define A 0\n" + " /* Code. Separated by blank line. */\n" + "\n" + "# define B 0\n" + " /* Code. Not aligned with # */\n" + "# define C 0\n" + "#endif"; + const char *ToFormat = "" + "void f() {\n" + "#if 1\n" + "/* Preprocessor aligned. */\n" + "# define A 0\n" + "/* Code. Separated by blank line. */\n" + "\n" + "# define B 0\n" + " /* Code. Not aligned with # */\n" + "# define C 0\n" + "#endif"; + EXPECT_EQ(Expected, format(ToFormat, Style)); + EXPECT_EQ(Expected, format(Expected, Style)); + } + // Keep comments aligned with un-indented directives. + { + const char *Expected = "" + "void f() {\n" + "// Preprocessor aligned.\n" + "#define A 0\n" + " // Code. Separated by blank line.\n" + "\n" + "#define B 0\n" + " // Code. Not aligned with #\n" + "#define C 0\n"; + const char *ToFormat = "" + "void f() {\n" + "// Preprocessor aligned.\n" + "#define A 0\n" + "// Code. Separated by blank line.\n" + "\n" + "#define B 0\n" + " // Code. Not aligned with #\n" + "#define C 0\n"; + EXPECT_EQ(Expected, format(ToFormat, Style)); + EXPECT_EQ(Expected, format(Expected, Style)); + } // Test with tabs. Style.UseTab = FormatStyle::UT_Always; Style.IndentWidth = 8; -- cgit v1.2.3