[PATCH] D31114: Refactor `initTargetOptions` out of `EmitAssemblyHelper::CreateTargetMachine` and use it to initialize TargetOptions for ThinLTO Backends
mehdi_amini created this revision. Herald added a subscriber: Prazek. https://reviews.llvm.org/D31114 Files: clang/lib/CodeGen/BackendUtil.cpp Index: clang/lib/CodeGen/BackendUtil.cpp === --- clang/lib/CodeGen/BackendUtil.cpp +++ clang/lib/CodeGen/BackendUtil.cpp @@ -294,6 +294,88 @@ MPM->add(createRewriteSymbolsPass(DL)); } +static void initTargetOptions(llvm::TargetOptions &Options, + const CodeGenOptions &CodeGenOpts, + const clang::TargetOptions &TargetOpts, + const LangOptions &LangOpts, + const HeaderSearchOptions &HSOpts + + ) { + Options.ThreadModel = + llvm::StringSwitch(CodeGenOpts.ThreadModel) + .Case("posix", llvm::ThreadModel::POSIX) + .Case("single", llvm::ThreadModel::Single); + + // Set float ABI type. + assert((CodeGenOpts.FloatABI == "soft" || CodeGenOpts.FloatABI == "softfp" || + CodeGenOpts.FloatABI == "hard" || CodeGenOpts.FloatABI.empty()) && + "Invalid Floating Point ABI!"); + Options.FloatABIType = + llvm::StringSwitch(CodeGenOpts.FloatABI) + .Case("soft", llvm::FloatABI::Soft) + .Case("softfp", llvm::FloatABI::Soft) + .Case("hard", llvm::FloatABI::Hard) + .Default(llvm::FloatABI::Default); + + // Set FP fusion mode. + switch (CodeGenOpts.getFPContractMode()) { + case CodeGenOptions::FPC_Off: +Options.AllowFPOpFusion = llvm::FPOpFusion::Strict; +break; + case CodeGenOptions::FPC_On: +Options.AllowFPOpFusion = llvm::FPOpFusion::Standard; +break; + case CodeGenOptions::FPC_Fast: +Options.AllowFPOpFusion = llvm::FPOpFusion::Fast; +break; + } + + Options.UseInitArray = CodeGenOpts.UseInitArray; + Options.DisableIntegratedAS = CodeGenOpts.DisableIntegratedAS; + Options.CompressDebugSections = CodeGenOpts.CompressDebugSections; + Options.RelaxELFRelocations = CodeGenOpts.RelaxELFRelocations; + + // Set EABI version. + Options.EABIVersion = llvm::StringSwitch(TargetOpts.EABIVersion) +.Case("4", llvm::EABI::EABI4) +.Case("5", llvm::EABI::EABI5) +.Case("gnu", llvm::EABI::GNU) +.Default(llvm::EABI::Default); + + if (LangOpts.SjLjExceptions) +Options.ExceptionModel = llvm::ExceptionHandling::SjLj; + + Options.NoInfsFPMath = CodeGenOpts.NoInfsFPMath; + Options.NoNaNsFPMath = CodeGenOpts.NoNaNsFPMath; + Options.NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS; + Options.UnsafeFPMath = CodeGenOpts.UnsafeFPMath; + Options.StackAlignmentOverride = CodeGenOpts.StackAlignment; + Options.FunctionSections = CodeGenOpts.FunctionSections; + Options.DataSections = CodeGenOpts.DataSections; + Options.UniqueSectionNames = CodeGenOpts.UniqueSectionNames; + Options.EmulatedTLS = CodeGenOpts.EmulatedTLS; + Options.DebuggerTuning = CodeGenOpts.getDebuggerTuning(); + + Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll; + Options.MCOptions.MCSaveTempLabels = CodeGenOpts.SaveTempLabels; + Options.MCOptions.MCUseDwarfDirectory = !CodeGenOpts.NoDwarfDirectoryAsm; + Options.MCOptions.MCNoExecStack = CodeGenOpts.NoExecStack; + Options.MCOptions.MCIncrementalLinkerCompatible = + CodeGenOpts.IncrementalLinkerCompatible; + Options.MCOptions.MCPIECopyRelocations = CodeGenOpts.PIECopyRelocations; + Options.MCOptions.MCFatalWarnings = CodeGenOpts.FatalWarnings; + Options.MCOptions.AsmVerbose = CodeGenOpts.AsmVerbose; + Options.MCOptions.PreserveAsmComments = CodeGenOpts.PreserveAsmComments; + Options.MCOptions.ABIName = TargetOpts.ABI; + for (const auto &Entry : HSOpts.UserEntries) +if (!Entry.IsFramework && +(Entry.Group == frontend::IncludeDirGroup::Quoted || + Entry.Group == frontend::IncludeDirGroup::Angled || + Entry.Group == frontend::IncludeDirGroup::System)) + Options.MCOptions.IASSearchPaths.push_back( + Entry.IgnoreSysRoot ? Entry.Path : HSOpts.Sysroot + Entry.Path); +} + void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM, legacy::FunctionPassManager &FPM) { // Handle disabling of all LLVM passes, where we want to preserve the @@ -538,81 +620,7 @@ } llvm::TargetOptions Options; - - Options.ThreadModel = -llvm::StringSwitch(CodeGenOpts.ThreadModel) - .Case("posix", llvm::ThreadModel::POSIX) - .Case("single", llvm::ThreadModel::Single); - - // Set float ABI type. - assert((CodeGenOpts.FloatABI == "soft" || CodeGenOpts.FloatABI == "softfp" || - CodeGenOpts.FloatABI == "hard" || CodeGenOpts.FloatABI.empty()) && - "Invalid Floating Point ABI!"); - Options.FloatABIType = - llvm::StringSwitch(CodeGenOpts.FloatABI) - .Case("soft", llvm::FloatABI::Soft) - .Case("softfp", llvm::FloatABI
[PATCH] D30806: [nonnull] Teach Clang to attach the nonnull LLVM attribute to declarations and calls instead of just definitions, and then teach it to *not* attach such attributes even if the source c
chandlerc updated this revision to Diff 92245. chandlerc added a comment. Update with fixes suggested in review. https://reviews.llvm.org/D30806 Files: include/clang/AST/ASTContext.h include/clang/Basic/Builtins.def lib/AST/ASTContext.cpp lib/CodeGen/CGCall.cpp test/CodeGen/nonnull.c Index: test/CodeGen/nonnull.c === --- test/CodeGen/nonnull.c +++ test/CodeGen/nonnull.c @@ -49,3 +49,87 @@ // CHECK: define void @bar8(i32* nonnull %a, i32* nonnull %b) void bar8(int *a, int *b) __attribute__((nonnull)) __attribute__((nonnull(1))) {} + +// CHECK: declare void @foo_decl(i32* nonnull) +void foo_decl(int *__attribute__((nonnull))); + +// CHECK: declare void @bar_decl(i32* nonnull) +void bar_decl(int *) __attribute__((nonnull(1))); + +// CHECK: declare void @bar2_decl(i32*, i32* nonnull) +void bar2_decl(int *, int *) __attribute__((nonnull(2))); + +// CHECK: declare nonnull i32* @bar3_decl() +int *bar3_decl(void) __attribute__((returns_nonnull)); + +// CHECK: declare i32 @bar4_decl(i32, i32* nonnull) +int bar4_decl(int, int *) __attribute__((nonnull)); + +// CHECK: declare i32 @bar5_decl(i32, i32* nonnull) +int bar5_decl(int, int *) __attribute__((nonnull(1, 2))); + +// CHECK: declare i32 @bar6_decl(i64) +int bar6_decl(TransparentUnion) __attribute__((nonnull(1))); + +// CHECK: declare void @bar7_decl(i32* nonnull, i32* nonnull) +void bar7_decl(int *, int *) +__attribute__((nonnull(1))) __attribute__((nonnull(2))); + +// CHECK: declare void @bar8_decl(i32* nonnull, i32* nonnull) +void bar8_decl(int *, int *) +__attribute__((nonnull)) __attribute__((nonnull(1))); + +// Clang specially disables nonnull attributes on some library builtin +// functions to work around the fact that the standard and some vendors mark +// them as nonnull even though they are frequently called in practice with null +// arguments if a corresponding size argument is zero. + +// CHECK: declare i8* @memcpy(i8*, i8*, i64) +void *memcpy(void *, const void *, unsigned long) +__attribute__((nonnull(1, 2))) __attribute__((returns_nonnull)); + +// CHECK: declare i32 @memcmp(i8*, i8*, i64) +int memcmp(const void *, const void *, unsigned long) __attribute__((nonnull(1, 2))); + +// CHECK: declare i8* @memmove(i8*, i8*, i64) +void *memmove(void *, const void *, unsigned long) +__attribute__((nonnull(1, 2))) __attribute__((returns_nonnull)); + +// CHECK: declare i8* @strncpy(i8*, i8*, i64) +char *strncpy(char *, const char *, unsigned long) +__attribute__((nonnull(1, 2))) __attribute__((returns_nonnull)); + +// CHECK: declare i32 @strncmp(i8*, i8*, i64) +int strncmp(const char *, const char *, unsigned long) __attribute__((nonnull(1, 2))); + +// CHECK: declare nonnull i8* @strncat(i8* nonnull, i8*, i64) +char *strncat(char *, const char *, unsigned long) +__attribute__((nonnull(1, 2))) __attribute__((returns_nonnull)); + +// CHECK: declare i8* @memchr(i8*, i32, i64) +void *memchr(const void *__attribute__((nonnull)), int, unsigned long) +__attribute__((returns_nonnull)); + +// CHECK: declare i8* @memset(i8*, i32, i64) +void *memset(void *__attribute__((nonnull)), int, unsigned long) +__attribute__((returns_nonnull)); + +void use_declarations(int *p, void *volatile *sink) { + foo_decl(p); + bar_decl(p); + bar2_decl(p, p); + (void)bar3_decl(); + bar4_decl(42, p); + bar5_decl(42, p); + bar6_decl(p); + bar7_decl(p, p); + bar8_decl(p, p); + *sink = (void *)&memcpy; + *sink = (void *)&memcmp; + *sink = (void *)&memmove; + *sink = (void *)&strncpy; + *sink = (void *)&strncmp; + *sink = (void *)&strncat; + *sink = (void *)&memchr; + *sink = (void *)&memset; +} Index: lib/CodeGen/CGCall.cpp === --- lib/CodeGen/CGCall.cpp +++ lib/CodeGen/CGCall.cpp @@ -1759,6 +1759,34 @@ F.addAttributes(llvm::AttributeSet::FunctionIndex, AS); } +/// Returns the attribute (either parameter attribute, or function +/// attribute), which declares argument ArgNo to be non-null. +static const NonNullAttr *getNonNullAttr(const Decl *FD, const ParmVarDecl *PVD, + QualType ArgType, unsigned ArgNo) { + // FIXME: __attribute__((nonnull)) can also be applied to: + // - references to pointers, where the pointee is known to be + // nonnull (apparently a Clang extension) + // - transparent unions containing pointers + // In the former case, LLVM IR cannot represent the constraint. In + // the latter case, we have no guarantee that the transparent union + // is in fact passed as a pointer. + if (!ArgType->isAnyPointerType() && !ArgType->isBlockPointerType()) +return nullptr; + // First, check attribute on parameter itself. + if (PVD) { +if (auto ParmNNAttr = PVD->getAttr()) + return ParmNNAttr; + } + // Check function attributes. + if (!FD) +return nullptr; + for (const auto *NNAttr : FD->specific_attrs()) { +if (NN
[PATCH] D30806: [nonnull] Teach Clang to attach the nonnull LLVM attribute to declarations and calls instead of just definitions, and then teach it to *not* attach such attributes even if the source c
chandlerc marked an inline comment as done. chandlerc added a comment. Function argument order fixed. https://reviews.llvm.org/D30806 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r298177 - [X86] Add NumRegisterParameters Module Flag.
Author: niravd Date: Fri Mar 17 19:43:39 2017 New Revision: 298177 URL: http://llvm.org/viewvc/llvm-project?rev=298177&view=rev Log: [X86] Add NumRegisterParameters Module Flag. Reviewers: rnk, mkuper Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D27051 Added: cfe/trunk/test/CodeGen/pr3997.c Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp cfe/trunk/test/Headers/altivec-header.c Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=298177&r1=298176&r2=298177&view=diff == --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original) +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Fri Mar 17 19:43:39 2017 @@ -159,6 +159,12 @@ CodeGenModule::CodeGenModule(ASTContext // CoverageMappingModuleGen object. if (CodeGenOpts.CoverageMapping) CoverageMapping.reset(new CoverageMappingModuleGen(*this, *CoverageInfo)); + + // Record mregparm value now so it is visible through rest of codegen. + if (Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86) +getModule().addModuleFlag(llvm::Module::Error, "NumRegisterParameters", + CodeGenOpts.NumRegisterParameters); + } CodeGenModule::~CodeGenModule() {} @@ -416,6 +422,7 @@ void CodeGenModule::Release() { (Context.getLangOpts().Modules || !LinkerOptionsMetadata.empty())) { EmitModuleLinkOptions(); } + if (CodeGenOpts.DwarfVersion) { // We actually want the latest version when there are conflicts. // We can change from Warning to Latest if such mode is supported. Added: cfe/trunk/test/CodeGen/pr3997.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/pr3997.c?rev=298177&view=auto == --- cfe/trunk/test/CodeGen/pr3997.c (added) +++ cfe/trunk/test/CodeGen/pr3997.c Fri Mar 17 19:43:39 2017 @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 %s -triple i386-unknown-linux-gnu -mregparm 3 -emit-llvm -o - | FileCheck %s + +void *memcpy(void *dest, const void *src, unsigned int n); + +void use_builtin_memcpy(void *dest, const void *src, unsigned int n) { + __builtin_memcpy(dest, src, n); +} + +void use_memcpy(void *dest, const void *src, unsigned int n) { + memcpy(dest, src, n); +} + +//CHECK: !{i32 1, !"NumRegisterParameters", i32 3} Modified: cfe/trunk/test/Headers/altivec-header.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Headers/altivec-header.c?rev=298177&r1=298176&r2=298177&view=diff == --- cfe/trunk/test/Headers/altivec-header.c (original) +++ cfe/trunk/test/Headers/altivec-header.c Fri Mar 17 19:43:39 2017 @@ -9,4 +9,4 @@ // CHECK: target triple = "powerpc64- // CHECK-NEXT: {{^$}} -// CHECK-NEXT: llvm.ident +// CHECK-NEXT: {{llvm\..*}} ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r298175 - [Modules] In case of lock timeout, fallback and build module
Author: bruno Date: Fri Mar 17 19:26:18 2017 New Revision: 298175 URL: http://llvm.org/viewvc/llvm-project?rev=298175&view=rev Log: [Modules] In case of lock timeout, fallback and build module Duncan's r298165 introduced the PCMCache mechanism, which guarantees that locks aren't necessary anymore for correctness but only for performance, by avoiding building it twice when possible. Change the logic to avoid an error but actually build the module in case the timeout happens. Instead of an error, still emit a remark for debugging purposes. rdar://problem/30297862 Modified: cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td cfe/trunk/lib/Frontend/CompilerInstance.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td?rev=298175&r1=298174&r2=298175&view=diff == --- cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td Fri Mar 17 19:26:18 2017 @@ -90,10 +90,10 @@ def err_module_unavailable : Error< "module '%0' %select{is incompatible with|requires}1 feature '%2'">; def err_module_header_missing : Error< "%select{|umbrella }0header '%1' not found">; -def err_module_lock_failure : Error< - "could not acquire lock file for module '%0': %1">, DefaultFatal; -def err_module_lock_timeout : Error< - "timed out waiting to acquire lock file for module '%0'">, DefaultFatal; +def remark_module_lock_failure : Remark< + "could not acquire lock file for module '%0': %1">, InGroup; +def remark_module_lock_timeout : Remark< + "timed out waiting to acquire lock file for module '%0'">, InGroup; def err_module_cycle : Error<"cyclic dependency in module '%0': %1">, DefaultFatal; def err_module_prebuilt : Error< Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=298175&r1=298174&r2=298175&view=diff == --- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original) +++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Fri Mar 17 19:26:18 2017 @@ -1190,10 +1190,14 @@ static bool compileAndLoadModule(Compile llvm::LockFileManager Locked(ModuleFileName); switch (Locked) { case llvm::LockFileManager::LFS_Error: - Diags.Report(ModuleNameLoc, diag::err_module_lock_failure) + // PCMCache takes care of correctness and locks are only necessary for + // performance. Fallback to building the module in case of any lock + // related errors. + Diags.Report(ModuleNameLoc, diag::remark_module_lock_failure) << Module->Name << Locked.getErrorMessage(); - return false; - + // Clear out any potential leftover. + Locked.unsafeRemoveLockFile(); + // FALLTHROUGH case llvm::LockFileManager::LFS_Owned: // We're responsible for building the module ourselves. if (!compileModuleImpl(ImportingInstance, ModuleNameLoc, Module, @@ -1213,11 +1217,14 @@ static bool compileAndLoadModule(Compile case llvm::LockFileManager::Res_OwnerDied: continue; // try again to get the lock. case llvm::LockFileManager::Res_Timeout: -Diags.Report(ModuleNameLoc, diag::err_module_lock_timeout) +// Since PCMCache takes care of correctness, we try waiting for another +// process to complete the build so clang does not do it done twice. If +// case of timeout, build it ourselves. +Diags.Report(ModuleNameLoc, diag::remark_module_lock_timeout) << Module->Name; // Clear the lock file so that future invokations can make progress. Locked.unsafeRemoveLockFile(); -return false; +continue; } break; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r298170 - [index] For C++ constructors/destructors, add references to the parent type where its name appears in definitions and declarations
Author: akirtzidis Date: Fri Mar 17 18:41:59 2017 New Revision: 298170 URL: http://llvm.org/viewvc/llvm-project?rev=298170&view=rev Log: [index] For C++ constructors/destructors, add references to the parent type where its name appears in definitions and declarations Patch by Nathan Hawes! https://reviews.llvm.org/D30730 Modified: cfe/trunk/lib/Index/IndexDecl.cpp cfe/trunk/lib/Index/IndexingContext.h cfe/trunk/test/Index/Core/index-source.cpp Modified: cfe/trunk/lib/Index/IndexDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Index/IndexDecl.cpp?rev=298170&r1=298169&r2=298170&view=diff == --- cfe/trunk/lib/Index/IndexDecl.cpp (original) +++ cfe/trunk/lib/Index/IndexDecl.cpp Fri Mar 17 18:41:59 2017 @@ -158,6 +158,9 @@ public: handleDeclarator(D); if (const CXXConstructorDecl *Ctor = dyn_cast(D)) { + IndexCtx.handleReference(Ctor->getParent(), Ctor->getLocation(), + Ctor->getParent(), Ctor->getDeclContext()); + // Constructor initializers. for (const auto *Init : Ctor->inits()) { if (Init->isWritten()) { @@ -168,6 +171,12 @@ public: IndexCtx.indexBody(Init->getInit(), D, D); } } +} else if (const CXXDestructorDecl *Dtor = dyn_cast(D)) { + if (auto TypeNameInfo = Dtor->getNameInfo().getNamedTypeInfo()) { +IndexCtx.handleReference(Dtor->getParent(), + TypeNameInfo->getTypeLoc().getLocStart(), + Dtor->getParent(), Dtor->getDeclContext()); + } } if (D->isThisDeclarationADefinition()) { Modified: cfe/trunk/lib/Index/IndexingContext.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Index/IndexingContext.h?rev=298170&r1=298169&r2=298170&view=diff == --- cfe/trunk/lib/Index/IndexingContext.h (original) +++ cfe/trunk/lib/Index/IndexingContext.h Fri Mar 17 18:41:59 2017 @@ -71,7 +71,7 @@ public: bool handleReference(const NamedDecl *D, SourceLocation Loc, const NamedDecl *Parent, const DeclContext *DC, - SymbolRoleSet Roles, + SymbolRoleSet Roles = SymbolRoleSet(), ArrayRef Relations = None, const Expr *RefE = nullptr, const Decl *RefD = nullptr); Modified: cfe/trunk/test/Index/Core/index-source.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/Core/index-source.cpp?rev=298170&r1=298169&r2=298170&view=diff == --- cfe/trunk/test/Index/Core/index-source.cpp (original) +++ cfe/trunk/test/Index/Core/index-source.cpp Fri Mar 17 18:41:59 2017 @@ -2,13 +2,20 @@ // CHECK: [[@LINE+1]]:7 | class/C++ | Cls | [[Cls_USR:.*]] | | Def | rel: 0 class Cls { - // CHECK: [[@LINE+2]]:3 | constructor/C++ | Cls | c:@S@Cls@F@Cls#I# | __ZN3ClsC1Ei | Decl,RelChild | rel: 1 + // CHECK: [[@LINE+3]]:3 | constructor/C++ | Cls | c:@S@Cls@F@Cls#I# | __ZN3ClsC1Ei | Decl,RelChild | rel: 1 // CHECK-NEXT: RelChild | Cls | c:@S@Cls + // CHECK: [[@LINE+1]]:3 | class/C++ | Cls | c:@S@Cls | | Ref,RelCont | rel: 1 Cls(int x); - // CHECK: [[@LINE+1]]:3 | constructor/cxx-copy-ctor/C++ | Cls | c:@S@Cls@F@Cls#&1$@S@Cls# | __ZN3ClsC1ERKS_ | Decl,RelChild | rel: 1 + // CHECK: [[@LINE+2]]:3 | constructor/cxx-copy-ctor/C++ | Cls | c:@S@Cls@F@Cls#&1$@S@Cls# | __ZN3ClsC1ERKS_ | Decl,RelChild | rel: 1 + // CHECK: [[@LINE+1]]:3 | class/C++ | Cls | c:@S@Cls | | Ref,RelCont | rel: 1 Cls(const Cls &); - // CHECK: [[@LINE+1]]:3 | constructor/cxx-move-ctor/C++ | Cls | c:@S@Cls@F@Cls#&&$@S@Cls# | __ZN3ClsC1EOS_ | Decl,RelChild | rel: 1 + // CHECK: [[@LINE+2]]:3 | constructor/cxx-move-ctor/C++ | Cls | c:@S@Cls@F@Cls#&&$@S@Cls# | __ZN3ClsC1EOS_ | Decl,RelChild | rel: 1 + // CHECK: [[@LINE+1]]:3 | class/C++ | Cls | c:@S@Cls | | Ref,RelCont | rel: 1 Cls(Cls &&); + + // CHECK: [[@LINE+2]]:3 | destructor/C++ | ~Cls | c:@S@Cls@F@~Cls# | __ZN3ClsD1Ev | Decl,RelChild | rel: 1 + // CHECK: [[@LINE+1]]:4 | class/C++ | Cls | c:@S@Cls | | Ref,RelCont | rel: 1 + ~Cls(); }; // CHECK: [[@LINE+3]]:7 | class/C++ | SubCls1 | [[SubCls1_USR:.*]] | | Def | rel: 0 @@ -24,6 +31,16 @@ typedef Cls ClsAlias; // CHECK-NEXT: RelBase,RelCont | SubCls2 | [[SubCls2_USR]] class SubCls2 : public ClsAlias {}; +Cls::Cls(int x) {} +// CHECK: [[@LINE-1]]:6 | constructor/C++ | Cls | c:@S@Cls@F@Cls#I# | __ZN3ClsC1Ei | Def,RelChild | rel: 1 +// CHECK: [[@LINE-2]]:1 | class/C++ | Cls | c:@S@Cls | | Ref,RelCont | rel: 1 +// CHECK: [[@LINE-3]]:6 | class/C++ | Cls | c:@S@Cls | | Ref,RelCont | rel: 1 + +Cls::~/*a comment*/Cls() {} +// CHECK: [[@LINE-1]]:6 | destructor/C++ | ~Cls | c:@S@Cls@F@~Cls# | __ZN3ClsD1Ev | Def,Rel
[PATCH] D31007: [Objective-C] Miscellaneous -fobjc-weak Fixes
bkelley updated this revision to Diff 92220. bkelley added a comment. Integrated feedback from @rjmccall https://reviews.llvm.org/D31007 Files: include/clang/AST/Type.h lib/AST/Type.cpp lib/Sema/SemaCast.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaInit.cpp test/SemaObjCXX/objc-weak.mm Index: test/SemaObjCXX/objc-weak.mm === --- /dev/null +++ test/SemaObjCXX/objc-weak.mm @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-weak -fblocks -Wno-objc-root-class -std=c++98 -Wno-c++0x-extensions -verify %s + +@interface AnObject +@property(weak) id value; +@end + +__attribute__((objc_arc_weak_reference_unavailable)) +@interface NOWEAK : AnObject // expected-note 2 {{class is declared here}} +@end + +struct S { + __weak id a; // expected-note {{because type 'S' has a member with __weak ownership}} +}; + +union U { + __weak id a; // expected-error {{ARC forbids Objective-C objects in union}} + S b; // expected-error {{union member 'b' has a non-trivial copy constructor}} +}; + +void testCast(AnObject *o) { + __weak id a = reinterpret_cast<__weak NOWEAK *>(o); // expected-error {{class is incompatible with __weak references}} \ + // expected-error {{explicit ownership qualifier on cast result has no effect}} \ + // expected-error {{assignment of a weak-unavailable object to a __weak object}} + + __weak id b = static_cast<__weak NOWEAK *>(o); // expected-error {{class is incompatible with __weak references}} \ + // expected-error {{explicit ownership qualifier on cast result has no effect}} \ + // expected-error {{assignment of a weak-unavailable object to a __weak object}} +} Index: lib/Sema/SemaInit.cpp === --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -6678,8 +6678,7 @@ // need cleanups. Likewise if we're extending this temporary to automatic // storage duration -- we need to register its cleanup during the // full-expression's cleanups. - if ((S.getLangOpts().ObjCAutoRefCount && - MTE->getType()->isObjCLifetimeType()) || + if (MTE->getType()->isNonTrivialObjCLifetimeType() || (MTE->getStorageDuration() == SD_Automatic && MTE->getType().isDestructedType())) S.Cleanup.setExprNeedsCleanups(true); Index: lib/Sema/SemaDeclCXX.cpp === --- lib/Sema/SemaDeclCXX.cpp +++ lib/Sema/SemaDeclCXX.cpp @@ -7145,8 +7145,7 @@ // [...] nontrivally ownership-qualified types are [...] not trivially // default constructible, copy constructible, move constructible, copy // assignable, move assignable, or destructible [...] -if (S.getLangOpts().ObjCAutoRefCount && -FieldType.hasNonTrivialObjCLifetime()) { +if (FieldType.hasNonTrivialObjCLifetime()) { if (Diagnose) S.Diag(FI->getLocation(), diag::note_nontrivial_objc_ownership) << RD << FieldType.getObjCLifetime(); Index: lib/Sema/SemaDecl.cpp === --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -14492,7 +14492,7 @@ // Verify that all the fields are okay. SmallVector RecFields; - bool ARCErrReported = false; + bool ObjCFieldLifetimeErrReported = false; for (ArrayRef::iterator i = Fields.begin(), end = Fields.end(); i != end; ++i) { FieldDecl *FD = cast(*i); @@ -14627,16 +14627,16 @@ << FixItHint::CreateInsertion(FD->getLocation(), "*"); QualType T = Context.getObjCObjectPointerType(FD->getType()); FD->setType(T); -} else if (getLangOpts().ObjCAutoRefCount && Record && !ARCErrReported && +} else if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() && + Record && !ObjCFieldLifetimeErrReported && (!getLangOpts().CPlusPlus || Record->isUnion())) { - // It's an error in ARC if a field has lifetime. + // It's an error in ARC or Weak if a field has lifetime. // We don't want to report this in a system header, though, // so we just make the field unavailable. // FIXME: that's really not sufficient; we need to make the type // itself invalid to, say, initialize or copy. QualType T = FD->getType(); - Qualifiers::ObjCLifetime lifetime = T.getObjCLifetime(); - if (lifetime && lifetime != Qualifiers::OCL_ExplicitNone) { + if (T.hasNonTrivialObjCLifetime()) { SourceLocation loc = FD->getLocation(); if (getSourceManager().isInSystemHeader(loc)) { if (!FD->hasAttr()) { @@ -14647,7 +14647,7 @@ Diag(FD->getLocation(), diag::err_arc_objc_ob
[PATCH] D28299: Module: use PCMCache to manage memory buffers for pcm files.
dexonsmith closed this revision. dexonsmith marked an inline comment as done. dexonsmith added a comment. Thanks for the reviews! Committed in r298165. https://reviews.llvm.org/D28299 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r298165 - Modules: Cache PCMs in memory and avoid a use-after-free
Author: dexonsmith Date: Fri Mar 17 17:55:13 2017 New Revision: 298165 URL: http://llvm.org/viewvc/llvm-project?rev=298165&view=rev Log: Modules: Cache PCMs in memory and avoid a use-after-free Clang's internal build system for implicit modules uses lock files to ensure that after a process writes a PCM it will read the same one back in (without contention from other -cc1 commands). Since PCMs are read from disk repeatedly while invalidating, building, and importing, the lock is not released quickly. Furthermore, the LockFileManager is not robust in every environment. Other -cc1 commands can stall until timeout (after about eight minutes). This commit changes the lock file from being necessary for correctness to a (possibly dubious) performance hack. The remaining benefit is to reduce duplicate work in competing -cc1 commands which depend on the same module. Follow-up commits will change the internal build system to continue after a timeout, and reduce the timeout. Perhaps we should reconsider blocking at all. This also fixes a use-after-free, when one part of a compilation validates a PCM and starts using it, and another tries to swap out the PCM for something new. The PCMCache is a new type called MemoryBufferCache, which saves memory buffers based on their filename. Its ownership is shared by the CompilerInstance and ModuleManager. - The ModuleManager stores PCMs there that it loads from disk, never touching the disk if the cache is hot. - When modules fail to validate, they're removed from the cache. - When a CompilerInstance is spawned to build a new module, each already-loaded PCM is assumed to be valid, and is frozen to avoid the use-after-free. - Any newly-built module is written directly to the cache to avoid the round-trip to the filesystem, making lock files unnecessary for correctness. Original patch by Manman Ren; most testcases by Adrian Prantl! Added: cfe/trunk/include/clang/Basic/MemoryBufferCache.h cfe/trunk/lib/Basic/MemoryBufferCache.cpp cfe/trunk/test/Modules/Inputs/system-out-of-date/ cfe/trunk/test/Modules/Inputs/system-out-of-date/X.h cfe/trunk/test/Modules/Inputs/system-out-of-date/Y.h cfe/trunk/test/Modules/Inputs/system-out-of-date/Z.h cfe/trunk/test/Modules/Inputs/system-out-of-date/module.map cfe/trunk/test/Modules/Inputs/warning-mismatch/ cfe/trunk/test/Modules/Inputs/warning-mismatch/Mismatch.h cfe/trunk/test/Modules/Inputs/warning-mismatch/System.h cfe/trunk/test/Modules/Inputs/warning-mismatch/module.modulemap cfe/trunk/test/Modules/outofdate-rebuild.m cfe/trunk/test/Modules/system-out-of-date-test.m cfe/trunk/test/Modules/warning-mismatch.m cfe/trunk/unittests/Basic/MemoryBufferCacheTest.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td cfe/trunk/include/clang/Frontend/ASTUnit.h cfe/trunk/include/clang/Frontend/CompilerInstance.h cfe/trunk/include/clang/Lex/Preprocessor.h cfe/trunk/include/clang/Serialization/ASTReader.h cfe/trunk/include/clang/Serialization/ASTWriter.h cfe/trunk/include/clang/Serialization/Module.h cfe/trunk/include/clang/Serialization/ModuleManager.h cfe/trunk/lib/Basic/CMakeLists.txt cfe/trunk/lib/Frontend/ASTUnit.cpp cfe/trunk/lib/Frontend/CompilerInstance.cpp cfe/trunk/lib/Lex/Preprocessor.cpp cfe/trunk/lib/Serialization/ASTReader.cpp cfe/trunk/lib/Serialization/ASTWriter.cpp cfe/trunk/lib/Serialization/GeneratePCH.cpp cfe/trunk/lib/Serialization/ModuleManager.cpp cfe/trunk/unittests/Basic/CMakeLists.txt cfe/trunk/unittests/Basic/SourceManagerTest.cpp cfe/trunk/unittests/Lex/LexerTest.cpp cfe/trunk/unittests/Lex/PPCallbacksTest.cpp cfe/trunk/unittests/Lex/PPConditionalDirectiveRecordTest.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td?rev=298165&r1=298164&r2=298165&view=diff == --- cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td Fri Mar 17 17:55:13 2017 @@ -176,6 +176,11 @@ def warn_duplicate_module_file_extension "duplicate module file extension block name '%0'">, InGroup; +def warn_module_system_bit_conflict : Warning< + "module file '%0' was validated as a system module and is now being imported " + "as a non-system module; any difference in diagnostic options will be ignored">, + InGroup; + } // let CategoryName } // let Component Added: cfe/trunk/include/clang/Basic/MemoryBufferCache.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/MemoryBufferCache.h?rev=298165&view=auto == --- cfe/trunk/include/clang/Basic/MemoryBufferCac
[PATCH] D31005: [Objective-C] Fix "repeated use of weak" warning with -fobjc-weak
bkelley updated this revision to Diff 92218. bkelley added a comment. Updated with feedback from @jordan_rose and @arphaman https://reviews.llvm.org/D31005 Files: include/clang/AST/Type.h lib/AST/Type.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprMember.cpp lib/Sema/SemaExprObjC.cpp lib/Sema/SemaPseudoObject.cpp test/SemaObjC/arc-repeated-weak.mm Index: test/SemaObjC/arc-repeated-weak.mm === --- test/SemaObjC/arc-repeated-weak.mm +++ test/SemaObjC/arc-repeated-weak.mm @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -fblocks -Wno-objc-root-class -std=c++11 -Warc-repeated-use-of-weak -verify %s +// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-weak -fblocks -Wno-objc-root-class -std=c++11 -Warc-repeated-use-of-weak -verify %s @interface Test { @public @@ -445,8 +446,8 @@ @class NSString; @interface NSBundle +(NSBundle *)foo; -@property (class) NSBundle *foo2; -@property NSString *prop; +@property (class, strong) NSBundle *foo2; +@property (strong) NSString *prop; @property(weak) NSString *weakProp; @end @@ -473,5 +474,8 @@ }; void foo1() { - INTFPtrTy tmp = (INTFPtrTy)e1; // expected-error{{cast of 'E' to 'INTFPtrTy' (aka 'INTF *') is disallowed with ARC}} + INTFPtrTy tmp = (INTFPtrTy)e1; +#if __has_feature(objc_arc) +// expected-error@-2{{cast of 'E' to 'INTFPtrTy' (aka 'INTF *') is disallowed with ARC}} +#endif } Index: lib/Sema/SemaPseudoObject.cpp === --- lib/Sema/SemaPseudoObject.cpp +++ lib/Sema/SemaPseudoObject.cpp @@ -841,7 +841,7 @@ result = S.ImpCastExprToType(result.get(), propType, CK_BitCast); } } -if (S.getLangOpts().ObjCAutoRefCount) { +if (S.getLangOpts().ObjCWeak) { Qualifiers::ObjCLifetime LT = propType.getObjCLifetime(); if (LT == Qualifiers::OCL_Weak) if (!S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, RefExpr->getLocation())) @@ -962,11 +962,11 @@ } ExprResult ObjCPropertyOpBuilder::complete(Expr *SyntacticForm) { - if (S.getLangOpts().ObjCAutoRefCount && isWeakProperty() && + if (S.getLangOpts().ObjCWeak && isWeakProperty() && !S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, SyntacticForm->getLocStart())) - S.recordUseOfEvaluatedWeak(SyntacticRefExpr, - SyntacticRefExpr->isMessagingGetter()); +S.recordUseOfEvaluatedWeak(SyntacticRefExpr, + SyntacticRefExpr->isMessagingGetter()); return PseudoOpBuilder::complete(SyntacticForm); } Index: lib/Sema/SemaExprObjC.cpp === --- lib/Sema/SemaExprObjC.cpp +++ lib/Sema/SemaExprObjC.cpp @@ -3100,7 +3100,9 @@ // In ARC, check for message sends which are likely to introduce // retain cycles. checkRetainCycles(Result); + } + if (getLangOpts().ObjCWeak) { if (!isImplicit && Method) { if (const ObjCPropertyDecl *Prop = Method->findPropertyDecl()) { bool IsWeak = Index: lib/Sema/SemaExprMember.cpp === --- lib/Sema/SemaExprMember.cpp +++ lib/Sema/SemaExprMember.cpp @@ -1475,7 +1475,7 @@ } } bool warn = true; -if (S.getLangOpts().ObjCAutoRefCount) { +if (S.getLangOpts().ObjCWeak) { Expr *BaseExp = BaseExpr.get()->IgnoreParenImpCasts(); if (UnaryOperator *UO = dyn_cast(BaseExp)) if (UO->getOpcode() == UO_Deref) @@ -1502,7 +1502,7 @@ IV, IV->getUsageType(BaseType), MemberLoc, OpLoc, BaseExpr.get(), IsArrow); -if (S.getLangOpts().ObjCAutoRefCount) { +if (S.getLangOpts().ObjCWeak) { if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) { if (!S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, MemberLoc)) S.recordUseOfEvaluatedWeak(Result); Index: lib/Sema/SemaExpr.cpp === --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -704,7 +704,7 @@ // Loading a __weak object implicitly retains the value, so we need a cleanup to // balance that. - if (getLangOpts().ObjCAutoRefCount && + if (getLangOpts().ObjCWeak && E->getType().getObjCLifetime() == Qualifiers::OCL_Weak) Cleanup.setExprNeedsCleanups(true); @@ -2509,11 +2509,13 @@ ObjCIvarRefExpr(IV, IV->getUsageType(SelfExpr.get()->getType()), Loc, IV->getLocation(), SelfExpr.get(), true, true); - if (getLangOpts().ObjCAutoRefCount) { + if (getLangOpts().ObjCWeak) { if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) { if (!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc)) recordUseOfEvaluatedWeak(Result); } + } + if (g
[PATCH] D31006: [Objective-C] Fix "weak-unavailable" warning with -fobjc-weak
bkelley marked an inline comment as done. bkelley added inline comments. Comment at: lib/Sema/SemaCast.cpp:125 + assert(Self.getLangOpts().ObjCAutoRefCount || + Self.getLangOpts().ObjCWeak); rjmccall wrote: > Unlike the other patches, we do clearly need to be checking the language > options in places like this. Still, it's a shame to repeat the same > condition in a million places. > > I think the right thing to do here is to add a helper method to LangOpts: > > /// Returns true if any types in the program might have non-trivial > lifetime qualifiers. > bool allowsNonTrivialObjCLifetimeQualifiers() const { > return ObjCAutoRefCount || ObjCWeak; > } Thanks for the suggestion. I was hesitant to add a method to LangOpts since it has so few derived state functions, but it certainly makes everything else cleaner. https://reviews.llvm.org/D31006 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31007: [Objective-C] Miscellaneous -fobjc-weak Fixes
bkelley added a comment. Thanks for all the feedback! I think things are looking a lot better now. https://reviews.llvm.org/D31007 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31006: [Objective-C] Fix "weak-unavailable" warning with -fobjc-weak
bkelley updated this revision to Diff 92219. bkelley marked an inline comment as done. bkelley added a comment. Updated with feedback from @rjmccall https://reviews.llvm.org/D31006 Files: include/clang/Basic/LangOptions.h include/clang/Sema/Sema.h lib/Sema/SemaCast.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaExprObjC.cpp lib/Sema/SemaPseudoObject.cpp test/SemaObjC/arc-unavailable-for-weakref.m test/SemaObjCXX/arc-unavailable-for-weakref.mm Index: test/SemaObjCXX/arc-unavailable-for-weakref.mm === --- test/SemaObjCXX/arc-unavailable-for-weakref.mm +++ test/SemaObjCXX/arc-unavailable-for-weakref.mm @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -verify %s +// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-weak -verify %s // rdar://9693477 __attribute__((objc_arc_weak_reference_unavailable)) Index: test/SemaObjC/arc-unavailable-for-weakref.m === --- test/SemaObjC/arc-unavailable-for-weakref.m +++ test/SemaObjC/arc-unavailable-for-weakref.m @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-weak -verify -Wno-objc-root-class %s // rdar://9693477 __attribute__((objc_arc_weak_reference_unavailable)) Index: lib/Sema/SemaPseudoObject.cpp === --- lib/Sema/SemaPseudoObject.cpp +++ lib/Sema/SemaPseudoObject.cpp @@ -1127,8 +1127,8 @@ if (!Getter) return; QualType T = Getter->parameters()[0]->getType(); - S.CheckObjCARCConversion(Key->getSourceRange(), - T, Key, Sema::CCK_ImplicitConversion); + S.CheckObjCConversion(Key->getSourceRange(), T, Key, +Sema::CCK_ImplicitConversion); } bool ObjCSubscriptOpBuilder::findAtIndexGetter() { Index: lib/Sema/SemaExprObjC.cpp === --- lib/Sema/SemaExprObjC.cpp +++ lib/Sema/SemaExprObjC.cpp @@ -4108,11 +4108,10 @@ } Sema::ARCConversionResult -Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType, - Expr *&castExpr, CheckedConversionKind CCK, - bool Diagnose, - bool DiagnoseCFAudited, - BinaryOperatorKind Opc) { +Sema::CheckObjCConversion(SourceRange castRange, QualType castType, + Expr *&castExpr, CheckedConversionKind CCK, + bool Diagnose, bool DiagnoseCFAudited, + BinaryOperatorKind Opc) { QualType castExprType = castExpr->getType(); // For the purposes of the classification, we assume reference types @@ -4152,7 +4151,12 @@ } return ACR_okay; } - + + // The life-time qualifier cast check above is all we need for ObjCWeak. + // ObjCAutoRefCount has more restrictions on what is legal. + if (!getLangOpts().ObjCAutoRefCount) +return ACR_okay; + if (isAnyCLike(exprACTC) && isAnyCLike(castACTC)) return ACR_okay; // Allow all of these types to be cast to integer types (but not Index: lib/Sema/SemaExprCXX.cpp === --- lib/Sema/SemaExprCXX.cpp +++ lib/Sema/SemaExprCXX.cpp @@ -3744,10 +3744,9 @@ if (From->getType()->isObjCObjectPointerType() && ToType->isObjCObjectPointerType()) EmitRelatedResultTypeNote(From); -} -else if (getLangOpts().ObjCAutoRefCount && - !CheckObjCARCUnavailableWeakConversion(ToType, -From->getType())) { +} else if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() && + !CheckObjCARCUnavailableWeakConversion(ToType, + From->getType())) { if (Action == AA_Initializing) Diag(From->getLocStart(), diag::err_arc_weak_unavailable_assign); @@ -3770,8 +3769,8 @@ (void) PrepareCastToObjCObjectPointer(E); From = E.get(); } -if (getLangOpts().ObjCAutoRefCount) - CheckObjCARCConversion(SourceRange(), ToType, From, CCK); +if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers()) + CheckObjCConversion(SourceRange(), ToType, From, CCK); From = ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath, CCK) .get(); break; Index: lib/Sema/SemaExpr.cpp === --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -7700,7 +7700,7 @@ Kind = CK_BitCast; Sem
[PATCH] D31004: [Objective-C] Fix __weak type traits with -fobjc-weak
bkelley added a comment. Looks like we can simplify everything by using `hasNonTrivialObjCLifetime()`, like in https://reviews.llvm.org/D31003. https://reviews.llvm.org/D31004 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31004: [Objective-C] Fix __weak type traits with -fobjc-weak
bkelley updated this revision to Diff 92217. bkelley added a comment. Updated with feedback from @rjmccall https://reviews.llvm.org/D31004 Files: lib/AST/Type.cpp lib/Sema/SemaExprCXX.cpp test/SemaObjCXX/objc-weak-type-traits.mm Index: test/SemaObjCXX/objc-weak-type-traits.mm === --- /dev/null +++ test/SemaObjCXX/objc-weak-type-traits.mm @@ -0,0 +1,210 @@ +// RUN: %clang_cc1 -fsyntax-only -fobjc-weak -fobjc-runtime-has-weak -verify -std=c++11 %s +// expected-no-diagnostics + +// Check the results of the various type-trait query functions on +// lifetime-qualified types in ObjC Weak. + +#define TRAIT_IS_TRUE(Trait, Type) static_assert(Trait(Type), "") +#define TRAIT_IS_FALSE(Trait, Type) static_assert(!Trait(Type), "") +#define TRAIT_IS_TRUE_2(Trait, Type1, Type2) static_assert(Trait(Type1, Type2), "") +#define TRAIT_IS_FALSE_2(Trait, Type1, Type2) static_assert(!Trait(Type1, Type2), "") + +struct HasStrong { id obj; }; +struct HasWeak { __weak id obj; }; +struct HasUnsafeUnretained { __unsafe_unretained id obj; }; + +// __has_nothrow_assign +TRAIT_IS_TRUE(__has_nothrow_assign, __strong id); +TRAIT_IS_TRUE(__has_nothrow_assign, __weak id); +TRAIT_IS_TRUE(__has_nothrow_assign, __autoreleasing id); +TRAIT_IS_TRUE(__has_nothrow_assign, __unsafe_unretained id); +TRAIT_IS_TRUE(__has_nothrow_assign, HasStrong); +TRAIT_IS_TRUE(__has_nothrow_assign, HasWeak); +TRAIT_IS_TRUE(__has_nothrow_assign, HasUnsafeUnretained); + +// __has_nothrow_copy +TRAIT_IS_TRUE(__has_nothrow_copy, __strong id); +TRAIT_IS_TRUE(__has_nothrow_copy, __weak id); +TRAIT_IS_TRUE(__has_nothrow_copy, __autoreleasing id); +TRAIT_IS_TRUE(__has_nothrow_copy, __unsafe_unretained id); +TRAIT_IS_TRUE(__has_nothrow_copy, HasStrong); +TRAIT_IS_TRUE(__has_nothrow_copy, HasWeak); +TRAIT_IS_TRUE(__has_nothrow_copy, HasUnsafeUnretained); + +// __has_nothrow_constructor +TRAIT_IS_TRUE(__has_nothrow_constructor, __strong id); +TRAIT_IS_TRUE(__has_nothrow_constructor, __weak id); +TRAIT_IS_TRUE(__has_nothrow_constructor, __autoreleasing id); +TRAIT_IS_TRUE(__has_nothrow_constructor, __unsafe_unretained id); +TRAIT_IS_TRUE(__has_nothrow_constructor, HasStrong); +TRAIT_IS_TRUE(__has_nothrow_constructor, HasWeak); +TRAIT_IS_TRUE(__has_nothrow_constructor, HasUnsafeUnretained); + +// __has_trivial_assign +TRAIT_IS_TRUE(__has_trivial_assign, __strong id); +TRAIT_IS_FALSE(__has_trivial_assign, __weak id); +TRAIT_IS_TRUE(__has_trivial_assign, __autoreleasing id); +TRAIT_IS_TRUE(__has_trivial_assign, __unsafe_unretained id); +TRAIT_IS_TRUE(__has_trivial_assign, HasStrong); +TRAIT_IS_FALSE(__has_trivial_assign, HasWeak); +TRAIT_IS_TRUE(__has_trivial_assign, HasUnsafeUnretained); + +// __has_trivial_copy +TRAIT_IS_TRUE(__has_trivial_copy, __strong id); +TRAIT_IS_FALSE(__has_trivial_copy, __weak id); +TRAIT_IS_TRUE(__has_trivial_copy, __autoreleasing id); +TRAIT_IS_TRUE(__has_trivial_copy, __unsafe_unretained id); +TRAIT_IS_TRUE(__has_trivial_copy, HasStrong); +TRAIT_IS_FALSE(__has_trivial_copy, HasWeak); +TRAIT_IS_TRUE(__has_trivial_copy, HasUnsafeUnretained); + +// __has_trivial_constructor +TRAIT_IS_TRUE(__has_trivial_constructor, __strong id); +TRAIT_IS_FALSE(__has_trivial_constructor, __weak id); +TRAIT_IS_TRUE(__has_trivial_constructor, __autoreleasing id); +TRAIT_IS_TRUE(__has_trivial_constructor, __unsafe_unretained id); +TRAIT_IS_TRUE(__has_trivial_constructor, HasStrong); +TRAIT_IS_FALSE(__has_trivial_constructor, HasWeak); +TRAIT_IS_TRUE(__has_trivial_constructor, HasUnsafeUnretained); + +// __has_trivial_destructor +TRAIT_IS_TRUE(__has_trivial_destructor, __strong id); +TRAIT_IS_FALSE(__has_trivial_destructor, __weak id); +TRAIT_IS_TRUE(__has_trivial_destructor, __autoreleasing id); +TRAIT_IS_TRUE(__has_trivial_destructor, __unsafe_unretained id); +TRAIT_IS_TRUE(__has_trivial_destructor, HasStrong); +TRAIT_IS_FALSE(__has_trivial_destructor, HasWeak); +TRAIT_IS_TRUE(__has_trivial_destructor, HasUnsafeUnretained); + +// __is_literal +TRAIT_IS_TRUE(__is_literal, __strong id); +TRAIT_IS_TRUE(__is_literal, __weak id); +TRAIT_IS_TRUE(__is_literal, __autoreleasing id); +TRAIT_IS_TRUE(__is_literal, __unsafe_unretained id); + +// __is_literal_type +TRAIT_IS_TRUE(__is_literal_type, __strong id); +TRAIT_IS_TRUE(__is_literal_type, __weak id); +TRAIT_IS_TRUE(__is_literal_type, __autoreleasing id); +TRAIT_IS_TRUE(__is_literal_type, __unsafe_unretained id); + +// __is_pod +TRAIT_IS_TRUE(__is_pod, __strong id); +TRAIT_IS_FALSE(__is_pod, __weak id); +TRAIT_IS_TRUE(__is_pod, __autoreleasing id); +TRAIT_IS_TRUE(__is_pod, __unsafe_unretained id); +TRAIT_IS_TRUE(__is_pod, HasStrong); +TRAIT_IS_FALSE(__is_pod, HasWeak); +TRAIT_IS_TRUE(__is_pod, HasUnsafeUnretained); + +// __is_trivial +TRAIT_IS_TRUE(__is_trivial, __strong id); +TRAIT_IS_FALSE(__is_trivial, __weak id); +TRAIT_IS_TRUE(__is_trivial, __autoreleasing id); +TRAIT_IS_TRUE(__is_trivial, __unsafe_unretained id); +TRAIT_IS_TRUE(__is_trivial, HasStr
[PATCH] D31005: [Objective-C] Fix "repeated use of weak" warning with -fobjc-weak
bkelley marked 3 inline comments as done. bkelley added inline comments. Comment at: lib/Sema/SemaDecl.cpp:10184 + (!getLangOpts().ObjCAutoRefCount && getLangOpts().ObjCWeak && + VDecl->getType().getObjCLifetime() != Qualifiers::OCL_Weak)) && !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, arphaman wrote: > jordan_rose wrote: > > bkelley wrote: > > > jordan_rose wrote: > > > > This condition's getting complicated, and it shows up in a few places. > > > > Would it make sense to factor it out? > > > What do you think about adding a member function like > > > `hasMRCNonTrivialWeakObjCLifetime(const ASTContext &Context)` to QualType > > > to factor out lines 10183-10184? We could use that in D31003, D31004, > > > here, and D31007. > > I'm fine with it myself but I don't work on Clang very much anymore. Maybe > > someone else can say whether it's actually a good idea. > > > > (By the way, the conventional abbreviation for this mode is "MRR" for > > "Manual Retain/Release", even though it's "ARC" and "Automated Reference > > Counting".) > Do you want to extract the out the entire > > ``` > (!getLangOpts().ObjCAutoRefCount && getLangOpts().ObjCWeak && > VDecl->getType().getObjCLifetime() != Qualifiers::OCL_Weak) > ``` > ? > > It looks like the others patches use only `getLangOpts().ObjCWeak && > Type.getObjCLifetime() != Qualifiers::OCL_Weak` so the use of > `hasMRCNonTrivialWeakObjCLifetime` won't be equivalent to the original code > in the other patches if you extract all code from lines 10183-10184. Yeah, my suspicion was that the addition of `!getLangOpts().ObjCAutoRefCount()` would have been fine, but most of the other code was simplified by using `hasNonTrivialObjCLifetime()` or another means, so this new function seems to only be necessary in this patch. I misnamed the proposed function, which would imply the qualifier is `OCL_Weak`, but we need //not// that, so my new proposed name is the odd looking `isNonWeakInMRRWithObjCWeak()`. Comment at: lib/Sema/SemaExpr.cpp:10340 - } else if (getLangOpts().ObjCAutoRefCount) { + } else if (getLangOpts().ObjCAutoRefCount || getLangOpts().ObjCWeak) { checkUnsafeExprAssigns(Loc, LHSExpr, RHS.get()); jordan_rose wrote: > bkelley wrote: > > jordan_rose wrote: > > > Does ObjCAutoRefCount imply ObjCWeak? If so, you could just use the > > > latter. > > I don't believe so. For Snow Leopard, ARC without weak references was > > supported so they can be independent. > Sure, but in that case we don't need the warning, right? Oh, I see. Yeah, looks like I can update most of the checks to just use ObjCWeak. I think we need both conditions here, however, since `checkUnsafeExprAssigns()` emits the "assigning retained object to unsafe property" warning, which is only applicable in ARC. https://reviews.llvm.org/D31005 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31003: [Objective-C] C++ Classes with __weak Members non-POD Types when using -fobjc-weak
bkelley marked 2 inline comments as done. bkelley added inline comments. Comment at: lib/Sema/SemaDeclCXX.cpp:4407 + (SemaRef.getLangOpts().ObjCWeak && +FieldBaseElementType.getObjCLifetime() == Qualifiers::OCL_Weak))) { +// ARC and Weak: rjmccall wrote: > I think this entire check can just be: > > if (FieldBaseElementType.hasNonTrivialObjCLifetime()) > > The language-options checks are almost certainly slower than just checking > the qualifiers. I see. `handleObjCOwnershipTypeAttr()` in SemaType.cpp only adds `OCL_Weak` or `OCL_ExplicitNone` outside of ARC and it's a compile error to use `__weak` without -fobjc-arc or -fobjc-weak, so `hasNonTrivialObjCLifetime()` is indeed much more simple. Thanks! https://reviews.llvm.org/D31003 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31003: [Objective-C] C++ Classes with __weak Members non-POD Types when using -fobjc-weak
bkelley updated this revision to Diff 92216. bkelley marked an inline comment as done. bkelley added a comment. Integrated feedback from @rjmccall https://reviews.llvm.org/D31003 Files: lib/AST/DeclCXX.cpp lib/Sema/SemaDeclCXX.cpp test/CodeGenObjCXX/objc-weak.mm Index: test/CodeGenObjCXX/objc-weak.mm === --- /dev/null +++ test/CodeGenObjCXX/objc-weak.mm @@ -0,0 +1,69 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-weak -fobjc-runtime-has-weak -std=c++11 -o - %s | FileCheck %s + +struct A { __weak id x; }; + +id test0() { + A a; + A b = a; + A c(static_cast(b)); + a = c; + c = static_cast(a); + return c.x; +} + +// Copy Assignment Operator +// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.A* @_ZN1AaSERKS_( +// CHECK: [[THISADDR:%this.*]] = alloca [[A:.*]]* +// CHECK: [[OBJECTADDR:%.*]] = alloca [[A:.*]]* +// CHECK: [[THIS:%this.*]] = load [[A]]*, [[A]]** [[THISADDR]] +// CHECK: [[OBJECT:%.*]] = load [[A]]*, [[A]]** [[OBJECTADDR]] +// CHECK: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[OBJECT]], i32 0, i32 0 +// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_loadWeak(i8** [[T0]]) +// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[A]], [[A]]* [[THIS]], i32 0, i32 0 +// CHECK-NEXT: [[T3:%.*]] = call i8* @objc_storeWeak(i8** [[T2]], i8* [[T1]]) + +// Move Assignment Operator +// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.A* @_ZN1AaSEOS_( +// CHECK: [[THISADDR:%this.*]] = alloca [[A:.*]]* +// CHECK: [[OBJECTADDR:%.*]] = alloca [[A:.*]]* +// CHECK: [[THIS:%this.*]] = load [[A]]*, [[A]]** [[THISADDR]] +// CHECK: [[OBJECT:%.*]] = load [[A]]*, [[A]]** [[OBJECTADDR]] +// CHECK: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[OBJECT]], i32 0, i32 0 +// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_loadWeak(i8** [[T0]]) +// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[A]], [[A]]* [[THIS]], i32 0, i32 0 +// CHECK-NEXT: [[T3:%.*]] = call i8* @objc_storeWeak(i8** [[T2]], i8* [[T1]]) + +// Default Constructor +// CHECK-LABEL: define linkonce_odr void @_ZN1AC2Ev( +// CHECK: [[THISADDR:%this.*]] = alloca [[A:.*]]* +// CHECK: [[THIS:%this.*]] = load [[A]]*, [[A]]** [[THISADDR]] +// CHECK: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[THIS]], i32 0, i32 0 +// CHECK-NEXT: store i8* null, i8** [[T0]] + +// Copy Constructor +// CHECK-LABEL: define linkonce_odr void @_ZN1AC2ERKS_( +// CHECK: [[THISADDR:%this.*]] = alloca [[A:.*]]* +// CHECK: [[OBJECTADDR:%.*]] = alloca [[A:.*]]* +// CHECK: [[THIS:%this.*]] = load [[A]]*, [[A]]** [[THISADDR]] +// CHECK: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[THIS]], i32 0, i32 0 +// CHECK-NEXT: [[OBJECT:%.*]] = load [[A]]*, [[A]]** [[OBJECTADDR]] +// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[OBJECT]], i32 0, i32 0 +// CHECK-NEXT: call void @objc_copyWeak(i8** [[T0]], i8** [[T1]]) + +// Move Constructor +// CHECK-LABEL: define linkonce_odr void @_ZN1AC2EOS_( +// CHECK: [[THISADDR:%this.*]] = alloca [[A:.*]]* +// CHECK: [[OBJECTADDR:%.*]] = alloca [[A:.*]]* +// CHECK: [[THIS:%this.*]] = load [[A]]*, [[A]]** [[THISADDR]] +// CHECK: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[THIS]], i32 0, i32 0 +// CHECK-NEXT: [[OBJECT:%.*]] = load [[A]]*, [[A]]** [[OBJECTADDR]] +// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[OBJECT]], i32 0, i32 0 +// CHECK-NEXT: call void @objc_moveWeak(i8** [[T0]], i8** [[T1]]) + +// Destructor +// CHECK-LABEL: define linkonce_odr void @_ZN1AD2Ev( +// CHECK: [[THISADDR:%this.*]] = alloca [[A:.*]]* +// CHECK: [[THIS:%this.*]] = load [[A]]*, [[A]]** [[THISADDR]] +// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[THIS]], i32 0, i32 0 +// CHECK-NEXT: call void @objc_destroyWeak(i8** [[T0]]) + Index: lib/Sema/SemaDeclCXX.cpp === --- lib/Sema/SemaDeclCXX.cpp +++ lib/Sema/SemaDeclCXX.cpp @@ -4399,11 +4399,8 @@ } } - if (SemaRef.getLangOpts().ObjCAutoRefCount && - FieldBaseElementType->isObjCRetainableType() && - FieldBaseElementType.getObjCLifetime() != Qualifiers::OCL_None && - FieldBaseElementType.getObjCLifetime() != Qualifiers::OCL_ExplicitNone) { -// ARC: + if (FieldBaseElementType.hasNonTrivialObjCLifetime()) { +// ARC and Weak: // Default-initialize Objective-C pointers to NULL. CXXMemberInit = new (SemaRef.Context) CXXCtorInitializer(SemaRef.Context, Field, Index: lib/AST/DeclCXX.cpp === --- lib/AST/DeclCXX.cpp +++ lib/AST/DeclCXX.cpp @@ -722,9 +722,7 @@ ASTContext &Context = getASTContext(); QualType T = Context.getBaseElementType(Field->getType()); if (T->isObjCRetainableType() || T
r298160 - [Sema] Unbreak GCC -Werror build (enum compare).
Author: davide Date: Fri Mar 17 17:19:20 2017 New Revision: 298160 URL: http://llvm.org/viewvc/llvm-project?rev=298160&view=rev Log: [Sema] Unbreak GCC -Werror build (enum compare). Modified: cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp Modified: cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp?rev=298160&r1=298159&r2=298160&view=diff == --- cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp (original) +++ cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp Fri Mar 17 17:19:20 2017 @@ -596,8 +596,8 @@ bool Sema::BuildCXXNestedNameSpecifier(S } // Replacement '::' -> ':' is not allowed, just issue respective error. Diag(R.getNameLoc(), OnlyNamespace - ? diag::err_expected_namespace_name - : diag::err_expected_class_or_namespace) + ? unsigned(diag::err_expected_namespace_name) + : unsigned(diag::err_expected_class_or_namespace)) << IdInfo.Identifier << getLangOpts().CPlusPlus; if (NamedDecl *ND = R.getAsSingle()) Diag(ND->getLocation(), diag::note_entity_declared_at) ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
LLVM buildmaster will be updated and restarted tonight
Hello everyone, LLVM buildmaster will be updated and restarted after 5 PM Pacific time today. Thanks Galina ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D24886: Add [[clang::suppress(rule, ...)]] attribute
mgehre updated this revision to Diff 92211. mgehre marked an inline comment as done. mgehre added a comment. Update for review comments https://reviews.llvm.org/D24886 Files: include/clang/Basic/Attr.td include/clang/Basic/AttrDocs.td lib/Sema/SemaDeclAttr.cpp lib/Sema/SemaStmtAttr.cpp test/SemaCXX/suppress.cpp Index: test/SemaCXX/suppress.cpp === --- /dev/null +++ test/SemaCXX/suppress.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only %s -verify + +[[clang::suppress("globally")]]; + +namespace N { + [[clang::suppress("in-a-namespace")]]; +} + +[[clang::suppress("readability-identifier-naming")]] +void f_() { + int *aVar_Name; + [[gsl::suppress("type", "bounds")]] { +aVar_Name = reinterpret_cast(7); + } + + [[clang::suppress]] int x; // expected-error {{'suppress' attribute takes at least 1 argument}} + [[clang::suppress()]] int y; // expected-error {{'suppress' attribute takes at least 1 argument}} + int [[clang::suppress("r")]] z; // expected-error {{'suppress' attribute cannot be applied to types}} + [[clang::suppress(f_)]] float f; // expected-error {{'suppress' attribute requires a string}} +} + +union [[gsl::suppress("type.1")]] U { + int i; + float f; +}; Index: lib/Sema/SemaStmtAttr.cpp === --- lib/Sema/SemaStmtAttr.cpp +++ lib/Sema/SemaStmtAttr.cpp @@ -53,6 +53,30 @@ return ::new (S.Context) auto(Attr); } +static Attr *handleSuppressAttr(Sema &S, Stmt *St, const AttributeList &A, +SourceRange Range) { + if (A.getNumArgs() < 1) { +S.Diag(A.getLoc(), diag::err_attribute_too_few_arguments) +<< A.getName() << 1; +return nullptr; + } + + std::vector DiagnosticIdentifiers; + for (unsigned I = 0, E = A.getNumArgs(); I != E; ++I) { +StringRef RuleName; +SourceLocation LiteralLoc; + +if (!S.checkStringLiteralArgumentAttr(A, I, RuleName, &LiteralLoc)) + return nullptr; + +DiagnosticIdentifiers.push_back(RuleName); + } + + return ::new (S.Context) SuppressAttr( + A.getRange(), S.Context, DiagnosticIdentifiers.data(), + DiagnosticIdentifiers.size(), A.getAttributeSpellingListIndex()); +} + static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const AttributeList &A, SourceRange) { IdentifierLoc *PragmaNameLoc = A.getArgAsIdent(0); @@ -279,6 +303,8 @@ return handleLoopHintAttr(S, St, A, Range); case AttributeList::AT_OpenCLUnrollHint: return handleOpenCLUnrollHint(S, St, A, Range); + case AttributeList::AT_Suppress: +return handleSuppressAttr(S, St, A, Range); default: // if we're here, then we parsed a known attribute, but didn't recognize // it as a statement attribute => it is declaration attribute Index: lib/Sema/SemaDeclAttr.cpp === --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -4075,6 +4075,25 @@ } } +static void handleSuppressAttr(Sema &S, Decl *D, const AttributeList &Attr) { + if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) +return; + + std::vector DiagnosticIdentifiers; + for (unsigned I = 0, E = Attr.getNumArgs(); I != E; ++I) { +StringRef RuleName; +SourceLocation LiteralLoc; + +if (!S.checkStringLiteralArgumentAttr(Attr, I, RuleName, &LiteralLoc)) + return; + +DiagnosticIdentifiers.push_back(RuleName); + } + D->addAttr(::new (S.Context) SuppressAttr( + Attr.getRange(), S.Context, DiagnosticIdentifiers.data(), + DiagnosticIdentifiers.size(), Attr.getAttributeSpellingListIndex())); +} + bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC, const FunctionDecl *FD) { if (attr.isInvalid()) @@ -6118,6 +6137,9 @@ case AttributeList::AT_PreserveAll: handleCallConvAttr(S, D, Attr); break; + case AttributeList::AT_Suppress: +handleSuppressAttr(S, D, Attr); +break; case AttributeList::AT_OpenCLKernel: handleSimpleAttribute(S, D, Attr); break; Index: include/clang/Basic/AttrDocs.td === --- include/clang/Basic/AttrDocs.td +++ include/clang/Basic/AttrDocs.td @@ -2723,6 +2723,32 @@ }]; } +def SuppressDocs : Documentation { + let Category = DocCatStmt; + let Content = [{ +The ``[[clang::suppress]]`` and ``[[gsl::suppress]]`` attributes can be used +to suppress specific clang-tidy warnings. The ``[[gsl::suppress]]`` is an +alias of ``[[clang::suppress]]`` which is intended to be used for suppressing +rules of the C++ Core Guidelines_ in a portable way. The attributes can be +attached to declarations, statements, and on namespace scope. + +.. code-block: c++ + [[clang::suppress("readability-identifier-naming")]] + void f_() { +int *aVar_Name; +[[gsl::suppress("type")]] { + aVar_Name = reint
[PATCH] D30848: Implement DR 373 "Lookup on namespace qualified name in using-directive"
This revision was automatically updated to reflect the committed changes. Closed by commit rL298126: Implement DR 373 "Lookup on namespace qualified name in using-directive" (authored by mgehre). Changed prior to commit: https://reviews.llvm.org/D30848?vs=91956&id=92209#toc Repository: rL LLVM https://reviews.llvm.org/D30848 Files: cfe/trunk/include/clang/Parse/Parser.h cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/Parse/ParseDeclCXX.cpp cfe/trunk/lib/Parse/ParseExprCXX.cpp cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp cfe/trunk/test/CXX/drs/dr3xx.cpp cfe/trunk/www/cxx_dr_status.html Index: cfe/trunk/www/cxx_dr_status.html === --- cfe/trunk/www/cxx_dr_status.html +++ cfe/trunk/www/cxx_dr_status.html @@ -2279,7 +2279,7 @@ http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#373";>373 C++11 Lookup on namespace qualified name in using-directive -No +SVN http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#374";>374 Index: cfe/trunk/include/clang/Parse/Parser.h === --- cfe/trunk/include/clang/Parse/Parser.h +++ cfe/trunk/include/clang/Parse/Parser.h @@ -1534,7 +1534,8 @@ bool EnteringContext, bool *MayBePseudoDestructor = nullptr, bool IsTypename = false, - IdentifierInfo **LastII = nullptr); + IdentifierInfo **LastII = nullptr, + bool OnlyNamespace = false); //======// // C++0x 5.1.2: Lambda expressions Index: cfe/trunk/include/clang/Sema/Sema.h === --- cfe/trunk/include/clang/Sema/Sema.h +++ cfe/trunk/include/clang/Sema/Sema.h @@ -5140,7 +5140,8 @@ CXXScopeSpec &SS, NamedDecl *ScopeLookupResult, bool ErrorRecoveryLookup, - bool *IsCorrectedToColon = nullptr); + bool *IsCorrectedToColon = nullptr, + bool OnlyNamespace = false); /// \brief The parser has parsed a nested-name-specifier 'identifier::'. /// @@ -5164,13 +5165,16 @@ /// are allowed. The bool value pointed by this parameter is set to 'true' /// if the identifier is treated as if it was followed by ':', not '::'. /// + /// \param OnlyNamespace If true, only considers namespaces in lookup. + /// /// \returns true if an error occurred, false otherwise. bool ActOnCXXNestedNameSpecifier(Scope *S, NestedNameSpecInfo &IdInfo, bool EnteringContext, CXXScopeSpec &SS, bool ErrorRecoveryLookup = false, - bool *IsCorrectedToColon = nullptr); + bool *IsCorrectedToColon = nullptr, + bool OnlyNamespace = false); ExprResult ActOnDecltypeExpression(Expr *E); Index: cfe/trunk/test/CXX/drs/dr3xx.cpp === --- cfe/trunk/test/CXX/drs/dr3xx.cpp +++ cfe/trunk/test/CXX/drs/dr3xx.cpp @@ -908,18 +908,21 @@ } } -namespace dr373 { // dr373: no - // FIXME: This is valid. - namespace X { int dr373; } // expected-note 2{{here}} +namespace dr373 { // dr373: 5 + namespace X { int dr373; } struct dr373 { // expected-note {{here}} void f() { - using namespace dr373::X; // expected-error {{no namespace named 'X' in 'dr373::dr373'}} + using namespace dr373::X; int k = dr373; // expected-error {{does not refer to a value}} - namespace Y = dr373::X; // expected-error {{no namespace named 'X' in 'dr373::dr373'}} + namespace Y = dr373::X; k = Y::dr373; } }; + + struct A { struct B {}; }; // expected-note 2{{here}} + namespace X = A::B; // expected-error {{expected namespace name}} + using namespace A::B; // expected-error {{expected namespace name}} } namespace dr374 { // dr374: yes c++11 Index: cfe/trunk/lib/Parse/ParseExprCXX.cpp === --- cfe/trunk/lib/Parse/ParseExprCXX.cpp +++ cfe/trunk/lib/Parse/ParseExprCXX.cpp @@ -141,13 +141,16 @@ /// filled in with the leading identifier in the last component of the /// nested-name-specifier, if any. /// +/// \param OnlyNamespace If true, only considers namespaces in lookup. +/// /// \returns true if there was an error parsing a scope specifier bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
r298126 - Implement DR 373 "Lookup on namespace qualified name in using-directive"
Author: mgehre Date: Fri Mar 17 16:41:20 2017 New Revision: 298126 URL: http://llvm.org/viewvc/llvm-project?rev=298126&view=rev Log: Implement DR 373 "Lookup on namespace qualified name in using-directive" Summary: 3.4.6 [basic.lookup.udir] paragraph 1: In a using-directive or namespace-alias-definition, during the lookup for a namespace-name or for a name in a nested-name-specifier, only namespace names are considered. Reviewers: rsmith, aaron.ballman Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D30848 Modified: cfe/trunk/include/clang/Parse/Parser.h cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/Parse/ParseDeclCXX.cpp cfe/trunk/lib/Parse/ParseExprCXX.cpp cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp cfe/trunk/test/CXX/drs/dr3xx.cpp cfe/trunk/www/cxx_dr_status.html Modified: cfe/trunk/include/clang/Parse/Parser.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=298126&r1=298125&r2=298126&view=diff == --- cfe/trunk/include/clang/Parse/Parser.h (original) +++ cfe/trunk/include/clang/Parse/Parser.h Fri Mar 17 16:41:20 2017 @@ -1534,7 +1534,8 @@ private: bool EnteringContext, bool *MayBePseudoDestructor = nullptr, bool IsTypename = false, - IdentifierInfo **LastII = nullptr); + IdentifierInfo **LastII = nullptr, + bool OnlyNamespace = false); //======// // C++0x 5.1.2: Lambda expressions Modified: cfe/trunk/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=298126&r1=298125&r2=298126&view=diff == --- cfe/trunk/include/clang/Sema/Sema.h (original) +++ cfe/trunk/include/clang/Sema/Sema.h Fri Mar 17 16:41:20 2017 @@ -5140,7 +5140,8 @@ public: CXXScopeSpec &SS, NamedDecl *ScopeLookupResult, bool ErrorRecoveryLookup, - bool *IsCorrectedToColon = nullptr); + bool *IsCorrectedToColon = nullptr, + bool OnlyNamespace = false); /// \brief The parser has parsed a nested-name-specifier 'identifier::'. /// @@ -5164,13 +5165,16 @@ public: /// are allowed. The bool value pointed by this parameter is set to 'true' /// if the identifier is treated as if it was followed by ':', not '::'. /// + /// \param OnlyNamespace If true, only considers namespaces in lookup. + /// /// \returns true if an error occurred, false otherwise. bool ActOnCXXNestedNameSpecifier(Scope *S, NestedNameSpecInfo &IdInfo, bool EnteringContext, CXXScopeSpec &SS, bool ErrorRecoveryLookup = false, - bool *IsCorrectedToColon = nullptr); + bool *IsCorrectedToColon = nullptr, + bool OnlyNamespace = false); ExprResult ActOnDecltypeExpression(Expr *E); Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=298126&r1=298125&r2=298126&view=diff == --- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original) +++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Fri Mar 17 16:41:20 2017 @@ -266,15 +266,26 @@ Decl *Parser::ParseNamespaceAlias(Source CXXScopeSpec SS; // Parse (optional) nested-name-specifier. - ParseOptionalCXXScopeSpecifier(SS, nullptr, /*EnteringContext=*/false); + ParseOptionalCXXScopeSpecifier(SS, nullptr, /*EnteringContext=*/false, + /*MayBePseudoDestructor=*/nullptr, + /*IsTypename=*/false, + /*LastII=*/nullptr, + /*OnlyNamespace=*/true); - if (SS.isInvalid() || Tok.isNot(tok::identifier)) { + if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_expected_namespace_name); // Skip to end of the definition and eat the ';'. SkipUntil(tok::semi); return nullptr; } + if (SS.isInvalid()) { +// Diagnostics have been emitted in ParseOptionalCXXScopeSpecifier. +// Skip to end of the definition and eat the ';'. +SkipUntil(tok::semi); +return nullptr; + } + // Parse identifier. IdentifierInfo *Ident = Tok.getIdentifierInfo(); SourceLocation IdentLoc = Consum
[PATCH] D30931: [clang-tidy] modified identifier naming case to use CT_AnyCase for ignoring case style
jutocz updated this revision to Diff 92205. jutocz added a comment. Updated diff to show full context https://reviews.llvm.org/D30931 Files: clang-tidy/readability/IdentifierNamingCheck.cpp clang-tidy/readability/IdentifierNamingCheck.h Index: clang-tidy/readability/IdentifierNamingCheck.h === --- clang-tidy/readability/IdentifierNamingCheck.h +++ clang-tidy/readability/IdentifierNamingCheck.h @@ -53,19 +53,16 @@ }; struct NamingStyle { -NamingStyle() : Case(CT_AnyCase) {} +NamingStyle() = default; -NamingStyle(CaseType Case, const std::string &Prefix, +NamingStyle(llvm::Optional Case, +const std::string &Prefix, const std::string &Suffix) : Case(Case), Prefix(Prefix), Suffix(Suffix) {} -CaseType Case; +llvm::Optional Case; std::string Prefix; std::string Suffix; - -bool isSet() const { - return !(Case == CT_AnyCase && Prefix.empty() && Suffix.empty()); -} }; /// \brief Holds an identifier name check failure, tracking the kind of the @@ -101,7 +98,7 @@ void expandMacro(const Token &MacroNameTok, const MacroInfo *MI); private: - std::vector NamingStyles; + std::vector > NamingStyles; bool IgnoreFailedSplit; NamingCheckFailureMap NamingCheckFailures; }; Index: clang-tidy/readability/IdentifierNamingCheck.cpp === --- clang-tidy/readability/IdentifierNamingCheck.cpp +++ clang-tidy/readability/IdentifierNamingCheck.cpp @@ -158,21 +158,28 @@ ClangTidyContext *Context) : ClangTidyCheck(Name, Context) { auto const fromString = [](StringRef Str) { -return llvm::StringSwitch(Str) +return llvm::StringSwitch >(Str) +.Case("aNy_CasE", CT_AnyCase) .Case("lower_case", CT_LowerCase) .Case("UPPER_CASE", CT_UpperCase) .Case("camelBack", CT_CamelBack) .Case("CamelCase", CT_CamelCase) .Case("Camel_Snake_Case", CT_CamelSnakeCase) .Case("camel_Snake_Back", CT_CamelSnakeBack) -.Default(CT_AnyCase); +.Default(llvm::Optional()); }; for (auto const &Name : StyleNames) { -NamingStyles.push_back( -NamingStyle(fromString(Options.get((Name + "Case").str(), "")), -Options.get((Name + "Prefix").str(), ""), -Options.get((Name + "Suffix").str(), ""))); +auto const caseOptional = +fromString(Options.get((Name + "Case").str(), "")); +auto prefix = Options.get((Name + "Prefix").str(), ""); +auto postfix = Options.get((Name + "Suffix").str(), ""); + +if (caseOptional.hasValue() || !prefix.empty() || !postfix.empty()) { + NamingStyles.push_back(NamingStyle(caseOptional, prefix, postfix)); +} else { + NamingStyles.push_back(llvm::Optional()); +} } IgnoreFailedSplit = Options.get("IgnoreFailedSplit", 0); @@ -201,12 +208,16 @@ }; for (size_t i = 0; i < SK_Count; ++i) { -Options.store(Opts, (StyleNames[i] + "Case").str(), - toString(NamingStyles[i].Case)); -Options.store(Opts, (StyleNames[i] + "Prefix").str(), - NamingStyles[i].Prefix); -Options.store(Opts, (StyleNames[i] + "Suffix").str(), - NamingStyles[i].Suffix); +if (NamingStyles[i].hasValue()) { + if (NamingStyles[i]->Case.hasValue()) { +Options.store(Opts, (StyleNames[i] + "Case").str(), + toString(NamingStyles[i]->Case.getValue())); + } + Options.store(Opts, (StyleNames[i] + "Prefix").str(), +NamingStyles[i]->Prefix); + Options.store(Opts, (StyleNames[i] + "Suffix").str(), +NamingStyles[i]->Suffix); +} } Options.store(Opts, "IgnoreFailedSplit", IgnoreFailedSplit); @@ -251,7 +262,8 @@ else Matches = false; - if (!Matchers[static_cast(Style.Case)].match(Name)) + if (Style.Case.hasValue() && + !Matchers[static_cast(Style.Case.getValue())].match(Name)) Matches = false; return Matches; @@ -354,38 +366,42 @@ } static std::string fixupWithStyle(StringRef Name, - IdentifierNamingCheck::NamingStyle Style) { - return Style.Prefix + fixupWithCase(Name, Style.Case) + Style.Suffix; +const IdentifierNamingCheck::NamingStyle &Style) { + return Style.Prefix + + fixupWithCase(Name, Style.Case.getValueOr( + IdentifierNamingCheck::CaseType::CT_AnyCase)) + + Style.Suffix; } static StyleKind findStyleKind( const NamedDecl *D, -const std::vector &NamingStyles) { - if (isa(D) && NamingStyles[SK_Typedef].isSet()) +const std::vector> +&NamingStyles) { + if (isa(D) && NamingStyles[SK_Typedef].hasValue()) return SK_Typedef; - if (isa(D) && NamingStyles[SK_TypeAlias].is
[PATCH] D31101: [ThinLTO] Use clang's existing code gen handling for ThinLTO backends
tejohnson created this revision. Herald added subscribers: Prazek, mehdi_amini. We noticed that when invoking the thinBackend via clang (for the distributed build case) that flags like -ffunction-sections and -emit-llvm were not having the intended effect. This could have been fixed by setting up the TargetOptions and the CodeGenFileType in the LTO Config, but since clang already has handling for all of this, it is straightforward to just let it do the handling (just below the early return after runThinLTOBackend being removed here). Depends on https://reviews.llvm.org/D31100. https://reviews.llvm.org/D31101 Files: lib/CodeGen/BackendUtil.cpp test/CodeGen/function-sections.c Index: test/CodeGen/function-sections.c === --- test/CodeGen/function-sections.c +++ test/CodeGen/function-sections.c @@ -9,6 +9,12 @@ // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -fdata-sections -o - < %s | FileCheck %s --check-prefix=DATA_SECT // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -fno-data-sections -fdata-sections -o - < %s | FileCheck %s --check-prefix=DATA_SECT +// Try again through a clang invocation of the ThinLTO backend. +// RUN: %clang -O2 %s -flto=thin -c -o %t.o +// RUN: llvm-lto -thinlto -o %t %t.o +// RUN: %clang -O2 -x ir %t.o -fthinlto-index=%t.thinlto.bc -S -ffunction-sections -o - | FileCheck %s --check-prefix=FUNC_SECT +// RUN: %clang -O2 -x ir %t.o -fthinlto-index=%t.thinlto.bc -S -fdata-sections -o - | FileCheck %s --check-prefix=DATA_SECT + const int hello = 123; void world() {} @@ -22,7 +28,7 @@ // FUNC_SECT: section .rodata, // FUNC_SECT: hello: -// DATA_SECT-NOT: section +// DATA_SECT-NOT: .section // DATA_SECT: world: // DATA_SECT: .section .rodata.hello, // DATA_SECT: hello: Index: lib/CodeGen/BackendUtil.cpp === --- lib/CodeGen/BackendUtil.cpp +++ lib/CodeGen/BackendUtil.cpp @@ -896,7 +896,6 @@ } static void runThinLTOBackend(ModuleSummaryIndex *CombinedIndex, Module *M, - std::unique_ptr OS, std::string SampleProfile) { StringMap> ModuleToDefinedGVSummaries; @@ -944,13 +943,11 @@ OwnedImports.push_back(std::move(*MBOrErr)); } - auto AddStream = [&](size_t Task) { -return llvm::make_unique(std::move(OS)); - }; lto::Config Conf; Conf.SampleProfile = SampleProfile; + Conf.SkipCodeGen = true; if (Error E = thinBackend( - Conf, 0, AddStream, *M, *CombinedIndex, ImportList, + Conf, 0, nullptr, *M, *CombinedIndex, ImportList, ModuleToDefinedGVSummaries[M->getModuleIdentifier()], ModuleMap)) { handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) { errs() << "Error running ThinLTO backend: " << EIB.message() << '\n'; @@ -983,11 +980,8 @@ // (LLVM will optionally ignore empty index files, returning null instead // of an error). bool DoThinLTOBackend = CombinedIndex != nullptr; -if (DoThinLTOBackend) { - runThinLTOBackend(CombinedIndex.get(), M, std::move(OS), -CGOpts.SampleProfileFile); - return; -} +if (DoThinLTOBackend) + runThinLTOBackend(CombinedIndex.get(), M, CGOpts.SampleProfileFile); } EmitAssemblyHelper AsmHelper(Diags, HeaderOpts, CGOpts, TOpts, LOpts, M); Index: test/CodeGen/function-sections.c === --- test/CodeGen/function-sections.c +++ test/CodeGen/function-sections.c @@ -9,6 +9,12 @@ // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -fdata-sections -o - < %s | FileCheck %s --check-prefix=DATA_SECT // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -fno-data-sections -fdata-sections -o - < %s | FileCheck %s --check-prefix=DATA_SECT +// Try again through a clang invocation of the ThinLTO backend. +// RUN: %clang -O2 %s -flto=thin -c -o %t.o +// RUN: llvm-lto -thinlto -o %t %t.o +// RUN: %clang -O2 -x ir %t.o -fthinlto-index=%t.thinlto.bc -S -ffunction-sections -o - | FileCheck %s --check-prefix=FUNC_SECT +// RUN: %clang -O2 -x ir %t.o -fthinlto-index=%t.thinlto.bc -S -fdata-sections -o - | FileCheck %s --check-prefix=DATA_SECT + const int hello = 123; void world() {} @@ -22,7 +28,7 @@ // FUNC_SECT: section .rodata, // FUNC_SECT: hello: -// DATA_SECT-NOT: section +// DATA_SECT-NOT: .section // DATA_SECT: world: // DATA_SECT: .section .rodata.hello, // DATA_SECT: hello: Index: lib/CodeGen/BackendUtil.cpp === --- lib/CodeGen/BackendUtil.cpp +++ lib/CodeGen/BackendUtil.cpp @@ -896,7 +896,6 @@ } static void runThinLTOBackend(ModuleSummaryIndex *CombinedIndex, Module *M, - std::unique_ptr OS, std::string SampleProfile) { StringMap> ModuleToDefinedGVSummaries; @@ -944,13 +943,11 @@ OwnedImports.push_back(st
[PATCH] D31097: [clang-tidy] don't warn about implicit widening casts in function calls
danielmarjamaki added a comment. In my opinion, we should stop warning about all implicit casts. Take for instance: long l1; if (condition) l1 = n << 8; // <- implicit cast else l1 = ~0L; That is fine. Nothing suspicious. Just because the destination variable is long doesn't have to mean the result is long. If we want to warn I would say that valueflow analysis should be used to see if there is truncation. The original idea was that we would warn if the user tried to cast the result but did that wrong. I don't feel that this is the idea of this checker anymore. Repository: rL LLVM https://reviews.llvm.org/D31097 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31097: [clang-tidy] don't warn about implicit widening casts in function calls
danielmarjamaki created this revision. Herald added a subscriber: JDevlieghere. This patch fixes https://bugs.llvm.org/show_bug.cgi?id=32246 To avoid spurious warnings, clang-tidy should not warn about misplaced widening casts for implicit casts in function calls. Repository: rL LLVM https://reviews.llvm.org/D31097 Files: clang-tidy/misc/MisplacedWideningCastCheck.cpp test/clang-tidy/misc-misplaced-widening-cast.cpp Index: test/clang-tidy/misc-misplaced-widening-cast.cpp === --- test/clang-tidy/misc-misplaced-widening-cast.cpp +++ test/clang-tidy/misc-misplaced-widening-cast.cpp @@ -45,8 +45,8 @@ } void call(unsigned int n) { + // Don't warn about implicit casts. See https://bugs.llvm.org/show_bug.cgi?id=32246 func(n << 8); - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: either cast from 'unsigned int' to 'long' func((long)(n << 8)); // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: either cast from 'unsigned int' to 'long' func((long)n << 8); Index: clang-tidy/misc/MisplacedWideningCastCheck.cpp === --- clang-tidy/misc/MisplacedWideningCastCheck.cpp +++ clang-tidy/misc/MisplacedWideningCastCheck.cpp @@ -46,7 +46,7 @@ Finder->addMatcher(varDecl(hasInitializer(Cast)), this); Finder->addMatcher(returnStmt(hasReturnValue(Cast)), this); - Finder->addMatcher(callExpr(hasAnyArgument(Cast)), this); + Finder->addMatcher(callExpr(hasAnyArgument(ExplicitCast.bind("Cast"))), this); Finder->addMatcher(binaryOperator(hasOperatorName("="), hasRHS(Cast)), this); Finder->addMatcher( binaryOperator(matchers::isComparisonOperator(), hasEitherOperand(Cast)), Index: test/clang-tidy/misc-misplaced-widening-cast.cpp === --- test/clang-tidy/misc-misplaced-widening-cast.cpp +++ test/clang-tidy/misc-misplaced-widening-cast.cpp @@ -45,8 +45,8 @@ } void call(unsigned int n) { + // Don't warn about implicit casts. See https://bugs.llvm.org/show_bug.cgi?id=32246 func(n << 8); - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: either cast from 'unsigned int' to 'long' func((long)(n << 8)); // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: either cast from 'unsigned int' to 'long' func((long)n << 8); Index: clang-tidy/misc/MisplacedWideningCastCheck.cpp === --- clang-tidy/misc/MisplacedWideningCastCheck.cpp +++ clang-tidy/misc/MisplacedWideningCastCheck.cpp @@ -46,7 +46,7 @@ Finder->addMatcher(varDecl(hasInitializer(Cast)), this); Finder->addMatcher(returnStmt(hasReturnValue(Cast)), this); - Finder->addMatcher(callExpr(hasAnyArgument(Cast)), this); + Finder->addMatcher(callExpr(hasAnyArgument(ExplicitCast.bind("Cast"))), this); Finder->addMatcher(binaryOperator(hasOperatorName("="), hasRHS(Cast)), this); Finder->addMatcher( binaryOperator(matchers::isComparisonOperator(), hasEitherOperand(Cast)), ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D29599: Clang Changes for alloc_align
erichkeane added a comment. Ping! https://reviews.llvm.org/D29599 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30931: [clang-tidy] modified identifier naming case to use CT_AnyCase for ignoring case style
alexfh added a comment. Could you generate a diff with full context (http://llvm.org/docs/Phabricator.html#requesting-a-review-via-the-web-interface)? https://reviews.llvm.org/D30931 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31049: [Clang-tidy] Fix for misc-noexcept-move-constructor false triggers on defaulted declarations
This revision was automatically updated to reflect the committed changes. Closed by commit rL298101: [Clang-tidy] Fix for misc-noexcept-move-constructor false triggers on defaulted… (authored by alexfh). Changed prior to commit: https://reviews.llvm.org/D31049?vs=92037&id=92159#toc Repository: rL LLVM https://reviews.llvm.org/D31049 Files: clang-tools-extra/trunk/clang-tidy/misc/NoexceptMoveConstructorCheck.cpp clang-tools-extra/trunk/test/clang-tidy/misc-noexcept-move-constructor.cpp Index: clang-tools-extra/trunk/test/clang-tidy/misc-noexcept-move-constructor.cpp === --- clang-tools-extra/trunk/test/clang-tidy/misc-noexcept-move-constructor.cpp +++ clang-tools-extra/trunk/test/clang-tidy/misc-noexcept-move-constructor.cpp @@ -42,3 +42,13 @@ OK3(OK3 &&) noexcept(false) {} OK3 &operator=(OK3 &&) = delete; }; + +struct OK4 { + OK4(OK4 &&) noexcept = default; + OK4 &operator=(OK4 &&) noexcept = default; +}; + +struct OK5 { + OK5(OK5 &&) noexcept(true) = default; + OK5 &operator=(OK5 &&) noexcept(true) = default; +}; Index: clang-tools-extra/trunk/clang-tidy/misc/NoexceptMoveConstructorCheck.cpp === --- clang-tools-extra/trunk/clang-tidy/misc/NoexceptMoveConstructorCheck.cpp +++ clang-tools-extra/trunk/clang-tidy/misc/NoexceptMoveConstructorCheck.cpp @@ -43,6 +43,10 @@ } const auto *ProtoType = Decl->getType()->getAs(); + +if (isUnresolvedExceptionSpec(ProtoType->getExceptionSpecType())) + return; + switch (ProtoType->getNoexceptSpec(*Result.Context)) { case FunctionProtoType::NR_NoNoexcept: diag(Decl->getLocation(), "move %0s should be marked noexcept") Index: clang-tools-extra/trunk/test/clang-tidy/misc-noexcept-move-constructor.cpp === --- clang-tools-extra/trunk/test/clang-tidy/misc-noexcept-move-constructor.cpp +++ clang-tools-extra/trunk/test/clang-tidy/misc-noexcept-move-constructor.cpp @@ -42,3 +42,13 @@ OK3(OK3 &&) noexcept(false) {} OK3 &operator=(OK3 &&) = delete; }; + +struct OK4 { + OK4(OK4 &&) noexcept = default; + OK4 &operator=(OK4 &&) noexcept = default; +}; + +struct OK5 { + OK5(OK5 &&) noexcept(true) = default; + OK5 &operator=(OK5 &&) noexcept(true) = default; +}; Index: clang-tools-extra/trunk/clang-tidy/misc/NoexceptMoveConstructorCheck.cpp === --- clang-tools-extra/trunk/clang-tidy/misc/NoexceptMoveConstructorCheck.cpp +++ clang-tools-extra/trunk/clang-tidy/misc/NoexceptMoveConstructorCheck.cpp @@ -43,6 +43,10 @@ } const auto *ProtoType = Decl->getType()->getAs(); + +if (isUnresolvedExceptionSpec(ProtoType->getExceptionSpecType())) + return; + switch (ProtoType->getNoexceptSpec(*Result.Context)) { case FunctionProtoType::NR_NoNoexcept: diag(Decl->getLocation(), "move %0s should be marked noexcept") ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r298101 - [Clang-tidy] Fix for misc-noexcept-move-constructor false triggers on defaulted declarations
Author: alexfh Date: Fri Mar 17 11:40:34 2017 New Revision: 298101 URL: http://llvm.org/viewvc/llvm-project?rev=298101&view=rev Log: [Clang-tidy] Fix for misc-noexcept-move-constructor false triggers on defaulted declarations Summary: There is no need for triggering warning when noexcept specifier in move constructor or move-assignment operator is neither evaluated nor uninstantiated. This fixes bug reported here: bugs.llvm.org/show_bug.cgi?id=24712 Reviewers: alexfh Reviewed By: alexfh Subscribers: JonasToth, JDevlieghere, cfe-commits Tags: #clang-tools-extra Patch by Marek Jenda! Differential Revision: https://reviews.llvm.org/D31049 Modified: clang-tools-extra/trunk/clang-tidy/misc/NoexceptMoveConstructorCheck.cpp clang-tools-extra/trunk/test/clang-tidy/misc-noexcept-move-constructor.cpp Modified: clang-tools-extra/trunk/clang-tidy/misc/NoexceptMoveConstructorCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/NoexceptMoveConstructorCheck.cpp?rev=298101&r1=298100&r2=298101&view=diff == --- clang-tools-extra/trunk/clang-tidy/misc/NoexceptMoveConstructorCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/misc/NoexceptMoveConstructorCheck.cpp Fri Mar 17 11:40:34 2017 @@ -43,6 +43,10 @@ void NoexceptMoveConstructorCheck::check } const auto *ProtoType = Decl->getType()->getAs(); + +if (isUnresolvedExceptionSpec(ProtoType->getExceptionSpecType())) + return; + switch (ProtoType->getNoexceptSpec(*Result.Context)) { case FunctionProtoType::NR_NoNoexcept: diag(Decl->getLocation(), "move %0s should be marked noexcept") Modified: clang-tools-extra/trunk/test/clang-tidy/misc-noexcept-move-constructor.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/misc-noexcept-move-constructor.cpp?rev=298101&r1=298100&r2=298101&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/misc-noexcept-move-constructor.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/misc-noexcept-move-constructor.cpp Fri Mar 17 11:40:34 2017 @@ -42,3 +42,13 @@ struct OK3 { OK3(OK3 &&) noexcept(false) {} OK3 &operator=(OK3 &&) = delete; }; + +struct OK4 { + OK4(OK4 &&) noexcept = default; + OK4 &operator=(OK4 &&) noexcept = default; +}; + +struct OK5 { + OK5(OK5 &&) noexcept(true) = default; + OK5 &operator=(OK5 &&) noexcept(true) = default; +}; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30977: [CodeGen] Emit a CoreFoundation link guard when @available is used
rjmccall accepted this revision. rjmccall added a comment. This revision is now accepted and ready to land. LGTM. Comment at: lib/CodeGen/CGObjC.cpp:3428 + // CoreFoundation is not used in the code, the linker won't link the + // framework. + auto &Context = getLLVMContext(); arphaman wrote: > rjmccall wrote: > > Can you explain why compiler-rt has to load the symbol at runtime? Is this > > just some compiler-rt testing thing? Because it seems like a shame to pay > > a code-size cost — even a negligible one — for something like that. > Because compiler-rt is linked into some internal projects that use the > `-all_load` flag, so the linker loads `__isOSVersionAtLeast` that references > the CoreFoundation symbols even when it's not used in code. Well, that is terrible. Repository: rL LLVM https://reviews.llvm.org/D30977 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30991: [Driver] Fix cross compiling with Visual Studio 2017
This revision was automatically updated to reflect the committed changes. Closed by commit rL298098: [clang-cl] Fix cross-compilation with MSVC 2017. (authored by zturner). Changed prior to commit: https://reviews.llvm.org/D30991?vs=92050&id=92154#toc Repository: rL LLVM https://reviews.llvm.org/D30991 Files: cfe/trunk/include/clang/Driver/Job.h cfe/trunk/lib/Driver/Job.cpp cfe/trunk/lib/Driver/ToolChains/MSVC.cpp Index: cfe/trunk/lib/Driver/ToolChains/MSVC.cpp === --- cfe/trunk/lib/Driver/ToolChains/MSVC.cpp +++ cfe/trunk/lib/Driver/ToolChains/MSVC.cpp @@ -446,6 +446,8 @@ TC.addProfileRTLibs(Args, CmdArgs); + std::vector Environment; + // We need to special case some linker paths. In the case of lld, we need to // translate 'lld' into 'lld-link', and in the case of the regular msvc // linker, we need to use a special search algorithm. @@ -459,14 +461,77 @@ // from the program PATH, because other environments like GnuWin32 install // their own link.exe which may come first. linkPath = FindVisualStudioExecutable(TC, "link.exe"); + +#ifdef USE_WIN32 +// When cross-compiling with VS2017 or newer, link.exe expects to have +// its containing bin directory at the top of PATH, followed by the +// native target bin directory. +// e.g. when compiling for x86 on an x64 host, PATH should start with: +// /bin/HostX64/x86;/bin/HostX64/x64 +if (TC.getIsVS2017OrNewer() && +llvm::Triple(llvm::sys::getProcessTriple()).getArch() != TC.getArch()) { + auto HostArch = llvm::Triple(llvm::sys::getProcessTriple()).getArch(); + + auto EnvBlockWide = + std::unique_ptr( + GetEnvironmentStringsW(), FreeEnvironmentStringsW); + if (!EnvBlockWide) +goto SkipSettingEnvironment; + + size_t EnvCount = 0; + size_t EnvBlockLen = 0; + while (EnvBlockWide[EnvBlockLen] != L'\0') { +++EnvCount; +EnvBlockLen += std::wcslen(&EnvBlockWide[EnvBlockLen]) + + 1 /*string null-terminator*/; + } + ++EnvBlockLen; // add the block null-terminator + + std::string EnvBlock; + if (!llvm::convertUTF16ToUTF8String( + llvm::ArrayRef(reinterpret_cast(EnvBlockWide.get()), + EnvBlockLen * sizeof(EnvBlockWide[0])), + EnvBlock)) +goto SkipSettingEnvironment; + + Environment.reserve(EnvCount); + + // Now loop over each string in the block and copy them into the + // environment vector, adjusting the PATH variable as needed when we + // find it. + for (const char *Cursor = EnvBlock.data(); *Cursor != '\0';) { +llvm::StringRef EnvVar(Cursor); +if (EnvVar.startswith_lower("path=")) { + using SubDirectoryType = toolchains::MSVCToolChain::SubDirectoryType; + constexpr size_t PrefixLen = 5; // strlen("path=") + Environment.push_back(Args.MakeArgString( + EnvVar.substr(0, PrefixLen) + + TC.getSubDirectoryPath(SubDirectoryType::Bin) + + llvm::Twine(llvm::sys::EnvPathSeparator) + + TC.getSubDirectoryPath(SubDirectoryType::Bin, HostArch) + + (EnvVar.size() > PrefixLen + ? llvm::Twine(llvm::sys::EnvPathSeparator) + + EnvVar.substr(PrefixLen) + : ""))); +} else { + Environment.push_back(Args.MakeArgString(EnvVar)); +} +Cursor += EnvVar.size() + 1 /*null-terminator*/; + } +} + SkipSettingEnvironment:; +#endif } else { linkPath = Linker; llvm::sys::path::replace_extension(linkPath, "exe"); linkPath = TC.GetProgramPath(linkPath.c_str()); } - const char *Exec = Args.MakeArgString(linkPath); - C.addCommand(llvm::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + auto LinkCmd = llvm::make_unique( + JA, *this, Args.MakeArgString(linkPath), CmdArgs, Inputs); + if (!Environment.empty()) +LinkCmd->setEnvironment(Environment); + C.addCommand(std::move(LinkCmd)); } void visualstudio::Compiler::ConstructJob(Compilation &C, const JobAction &JA, Index: cfe/trunk/lib/Driver/Job.cpp === --- cfe/trunk/lib/Driver/Job.cpp +++ cfe/trunk/lib/Driver/Job.cpp @@ -301,19 +301,33 @@ ResponseFileFlag += FileName; } +void Command::setEnvironment(llvm::ArrayRef NewEnvironment) { + Environment.reserve(NewEnvironment.size() + 1); + Environment.assign(NewEnvironment.begin(), NewEnvironment.end()); + Environment.push_back(nullptr); +} + int Command::Execute(const StringRef **Redirects, std::string *ErrMsg, bool *ExecutionFailed) const { SmallVector Argv; + const char **Envp; + if (Environment.empty()) { +Envp = nullptr; + } else { +assert(Environment.back() == nullptr && + "Environment vector shoul
r298098 - [clang-cl] Fix cross-compilation with MSVC 2017.
Author: zturner Date: Fri Mar 17 11:24:34 2017 New Revision: 298098 URL: http://llvm.org/viewvc/llvm-project?rev=298098&view=rev Log: [clang-cl] Fix cross-compilation with MSVC 2017. clang-cl works best when the user runs vcvarsall to set up an environment before running, but even this is not enough on VC 2017 when cross compiling (e.g. using an x64 toolchain to target x86, or vice versa). The reason is that although clang-cl itself will have a valid environment, it will shell out to other tools (such as link.exe) which may not. Generally we solve this through adding the appropriate linker flags, but this is not enough in VC 2017. The cross-linker and the regular linker both link against some common DLLs, but these DLLs live in the binary directory of the native linker. When setting up a cross-compilation environment through vcvarsall, it will add *both* directories to %PATH%, so that when cl shells out to any of the associated tools, those tools will be able to find all of the dependencies that it links against. If you don't do this, link.exe will fail to run because the loader won't be able to find all of the required DLLs that it links against. To solve this we teach the driver how to spawn a process with an explicitly specified environment. Then we modify the PATH before shelling out to subtools and run with the modified PATH. Patch by Hamza Sood Differential Revision: https://reviews.llvm.org/D30991 Modified: cfe/trunk/include/clang/Driver/Job.h cfe/trunk/lib/Driver/Job.cpp cfe/trunk/lib/Driver/ToolChains/MSVC.cpp Modified: cfe/trunk/include/clang/Driver/Job.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Job.h?rev=298098&r1=298097&r2=298098&view=diff == --- cfe/trunk/include/clang/Driver/Job.h (original) +++ cfe/trunk/include/clang/Driver/Job.h Fri Mar 17 11:24:34 2017 @@ -11,6 +11,7 @@ #define LLVM_CLANG_DRIVER_JOB_H #include "clang/Basic/LLVM.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/iterator.h" #include "llvm/Option/Option.h" @@ -69,6 +70,9 @@ class Command { /// file std::string ResponseFileFlag; + /// See Command::setEnvironment + std::vector Environment; + /// When a response file is needed, we try to put most arguments in an /// exclusive file, while others remains as regular command line arguments. /// This functions fills a vector with the regular command line arguments, @@ -111,6 +115,12 @@ public: InputFileList = std::move(List); } + /// \brief Sets the environment to be used by the new process. + /// \param NewEnvironment An array of environment variables. + /// \remark If the environment remains unset, then the environment + /// from the parent process will be used. + void setEnvironment(llvm::ArrayRef NewEnvironment); + const char *getExecutable() const { return Executable; } const llvm::opt::ArgStringList &getArguments() const { return Arguments; } Modified: cfe/trunk/lib/Driver/Job.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Job.cpp?rev=298098&r1=298097&r2=298098&view=diff == --- cfe/trunk/lib/Driver/Job.cpp (original) +++ cfe/trunk/lib/Driver/Job.cpp Fri Mar 17 11:24:34 2017 @@ -301,19 +301,33 @@ void Command::setResponseFile(const char ResponseFileFlag += FileName; } +void Command::setEnvironment(llvm::ArrayRef NewEnvironment) { + Environment.reserve(NewEnvironment.size() + 1); + Environment.assign(NewEnvironment.begin(), NewEnvironment.end()); + Environment.push_back(nullptr); +} + int Command::Execute(const StringRef **Redirects, std::string *ErrMsg, bool *ExecutionFailed) const { SmallVector Argv; + const char **Envp; + if (Environment.empty()) { +Envp = nullptr; + } else { +assert(Environment.back() == nullptr && + "Environment vector should be null-terminated by now"); +Envp = const_cast(Environment.data()); + } + if (ResponseFile == nullptr) { Argv.push_back(Executable); Argv.append(Arguments.begin(), Arguments.end()); Argv.push_back(nullptr); -return llvm::sys::ExecuteAndWait(Executable, Argv.data(), /*env*/ nullptr, - Redirects, /*secondsToWait*/ 0, - /*memoryLimit*/ 0, ErrMsg, - ExecutionFailed); +return llvm::sys::ExecuteAndWait( +Executable, Argv.data(), Envp, Redirects, /*secondsToWait*/ 0, +/*memoryLimit*/ 0, ErrMsg, ExecutionFailed); } // We need to put arguments in a response file (command is too large) @@ -337,8 +351,8 @@ int Command::Execute(const StringRef **R return -1; } - return llvm::sys::ExecuteAndWait(Executable, Argv.data(), /*env*/ nullptr, - Redirects, /*secondsToWait*/
[PATCH] D30848: Implement DR 373 "Lookup on namespace qualified name in using-directive"
rsmith accepted this revision. rsmith added a comment. This revision is now accepted and ready to land. Thanks, LGTM https://reviews.llvm.org/D30848 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r298097 - Test commit.
Author: dmgreen Date: Fri Mar 17 10:38:49 2017 New Revision: 298097 URL: http://llvm.org/viewvc/llvm-project?rev=298097&view=rev Log: Test commit. Modified: cfe/trunk/lib/Driver/ToolChains/Arch/ARM.h Modified: cfe/trunk/lib/Driver/ToolChains/Arch/ARM.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/Arch/ARM.h?rev=298097&r1=298096&r2=298097&view=diff == --- cfe/trunk/lib/Driver/ToolChains/Arch/ARM.h (original) +++ cfe/trunk/lib/Driver/ToolChains/Arch/ARM.h Fri Mar 17 10:38:49 2017 @@ -53,7 +53,7 @@ int getARMSubArchVersionNumber(const llv bool isARMMProfile(const llvm::Triple &Triple); } // end namespace arm -} // end namespace target +} // end namespace tools } // end namespace driver } // end namespace clang ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30295: [analyzer] clarify undef shift result when shift count is negative or exceeds the bit width
a.sidorin added inline comments. Comment at: lib/StaticAnalyzer/Core/CheckerHelpers.cpp:99 +bool clang::ento::isExprResultConformsComparisonRule(CheckerContext &C, + BinaryOperatorKind BOK, + const Expr *LExpr, a.sidorin wrote: > CompRule? Oops. I meant renaming of the BOK argument, not the method :) Sorry for misleading. Repository: rL LLVM https://reviews.llvm.org/D30295 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30295: [analyzer] clarify undef shift result when shift count is negative or exceeds the bit width
danielmarjamaki marked 2 inline comments as done. danielmarjamaki added inline comments. Comment at: lib/StaticAnalyzer/Core/CheckerHelpers.cpp:100 + BinaryOperatorKind BOK, + const Expr *LExpr, + const SVal RVal) { a.sidorin wrote: > I think we should rename these variables to LHSExpr, RHSVal, LHSVal. I don't > like LVal/RVal because they may be associated with rvalue/lvalue types which > is not what we want. I agree. Good point. Repository: rL LLVM https://reviews.llvm.org/D30295 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30295: [analyzer] clarify undef shift result when shift count is negative or exceeds the bit width
danielmarjamaki updated this revision to Diff 92150. danielmarjamaki added a comment. Fix review comments Repository: rL LLVM https://reviews.llvm.org/D30295 Files: include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h lib/StaticAnalyzer/Checkers/ConversionChecker.cpp lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp lib/StaticAnalyzer/Core/CheckerHelpers.cpp test/Analysis/bitwise-ops.c Index: test/Analysis/bitwise-ops.c === --- test/Analysis/bitwise-ops.c +++ test/Analysis/bitwise-ops.c @@ -29,4 +29,18 @@ default: return 0; } -} \ No newline at end of file +} + +int testOverflowShift(int a) { + if (a == 323) { +return 1 << a; // expected-warning{{The result of the '<<' expression is undefined due to shift count >= width of type}} + } + return 0; +} + +int testNegativeShift(int a) { + if (a == -5) { +return 1 << a; // expected-warning{{The result of the '<<' expression is undefined due to negative value on the right side of operand}} + } + return 0; +} Index: lib/StaticAnalyzer/Core/CheckerHelpers.cpp === --- lib/StaticAnalyzer/Core/CheckerHelpers.cpp +++ lib/StaticAnalyzer/Core/CheckerHelpers.cpp @@ -94,3 +94,39 @@ return std::make_pair(VD, RHS); } + +bool clang::ento::isExprResultConformsCompRule(CheckerContext &C, + BinaryOperatorKind BOK, + const Expr *LHSExpr, + const SVal RHSVal) { + ProgramStateRef State = C.getState(); + + SVal LHSVal = C.getSVal(LHSExpr); + if (LHSVal.isUnknownOrUndef() || !LHSVal.getAs()) +return false; + + SValBuilder &Bldr = C.getSValBuilder(); + SVal Eval = + Bldr.evalBinOp(State, BOK, LHSVal, RHSVal, Bldr.getConditionType()); + if (Eval.isUnknownOrUndef()) +return false; + + ConstraintManager &CM = C.getConstraintManager(); + ProgramStateRef StTrue, StFalse; + std::tie(StTrue, StFalse) = CM.assumeDual(State, Eval.castAs()); + return StTrue && !StFalse; +} + +// Is E value greater or equal than Val? +bool clang::ento::isGreaterEqual(CheckerContext &C, const Expr *E, + unsigned long long Val) { + DefinedSVal V = + C.getSValBuilder().makeIntVal(Val, C.getASTContext().LongLongTy); + return isExprResultConformsCompRule(C, BO_GE, E, V); +} + +// Is E value negative? +bool clang::ento::isNegative(CheckerContext &C, const Expr *E) { + DefinedSVal V = C.getSValBuilder().makeIntVal(0, false); + return isExprResultConformsCompRule(C, BO_LT, E, V); +} Index: lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp === --- lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp +++ lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp @@ -17,6 +17,7 @@ #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/raw_ostream.h" @@ -59,6 +60,11 @@ return StOutBound && !StInBound; } +bool isShiftOverflow(CheckerContext &C, const BinaryOperator *B) { + return isGreaterEqual(C, B->getRHS(), +C.getASTContext().getIntWidth(B->getLHS()->getType())); +} + void UndefResultChecker::checkPostStmt(const BinaryOperator *B, CheckerContext &C) const { ProgramStateRef state = C.getState(); @@ -106,9 +112,24 @@ } else { // Neither operand was undefined, but the result is undefined. - OS << "The result of the '" - << BinaryOperator::getOpcodeStr(B->getOpcode()) - << "' expression is undefined"; + if ((B->getOpcode() == BinaryOperatorKind::BO_Shl || + B->getOpcode() == BinaryOperatorKind::BO_Shr) && + isNegative(C, B->getRHS())) { +OS << "The result of the '" + << BinaryOperator::getOpcodeStr(B->getOpcode()) + << "' expression is undefined due to negative value on the right " + "side of operand"; + } else if ((B->getOpcode() == BinaryOperatorKind::BO_Shl || + B->getOpcode() == BinaryOperatorKind::BO_Shr) && + isShiftOverflow(C, B)) { +OS << "The result of the '" + << BinaryOperator::getOpcodeStr(B->getOpcode()) + << "' expression is undefined due to shift count >= width of type"; + } else { +OS << "The result of the '" + << BinaryOperator::getOpcodeStr(B->getOpcode()) + << "' expression is undefined"; + } } auto report = llvm::make_unique(*BT, OS.str(), N); if (Ex) { Index: lib/StaticAn
[PATCH] D31082: [mips][msa] Range adjustment for ldi_b builtin function operand
smaksimovic created this revision. Reasoning behind this change was allowing the function to accept all values from range [-128, 255] since all of them can be encoded in an 8bit wide value. This differs from the prior state where only range [-128, 127] was accepted, where values were assumed to be signed, whereas now the actual interpretation of the immediate is deferred to the consumer as required. https://reviews.llvm.org/D31082 Files: lib/Sema/SemaChecking.cpp test/CodeGen/builtins-mips-msa-error.c Index: test/CodeGen/builtins-mips-msa-error.c === --- test/CodeGen/builtins-mips-msa-error.c +++ test/CodeGen/builtins-mips-msa-error.c @@ -119,7 +119,7 @@ v4i32_r = __msa_ld_w(&v4i32_a, 512); // expected-error {{argument should be a value from -512 to 511}} v2i64_r = __msa_ld_d(&v2i64_a, 512); // expected-error {{argument should be a value from -512 to 511}} - v16i8_r = __msa_ldi_b(512);// expected-error {{argument should be a value from -512 to 511}} + v16i8_r = __msa_ldi_b(256);// expected-error {{argument should be a value from -128 to 255}} v8i16_r = __msa_ldi_h(512);// expected-error {{argument should be a value from -512 to 511}} v4i32_r = __msa_ldi_w(512);// expected-error {{argument should be a value from -512 to 511}} v2i64_r = __msa_ldi_d(512);// expected-error {{argument should be a value from -512 to 511}} @@ -310,7 +310,7 @@ v4i32_r = __msa_ld_w(&v4i32_a, -513); // expected-error {{argument should be a value from -512 to 511}} v2i64_r = __msa_ld_d(&v2i64_a, -513); // expected-error {{argument should be a value from -512 to 511}} - v16i8_r = __msa_ldi_b(-513); // expected-error {{argument should be a value from -512 to 511}} + v16i8_r = __msa_ldi_b(-129); // expected-error {{argument should be a value from -128 to 255}} v8i16_r = __msa_ldi_h(-513); // expected-error {{argument should be a value from -512 to 511}} v4i32_r = __msa_ldi_w(-513); // expected-error {{argument should be a value from -512 to 511}} v2i64_r = __msa_ldi_d(-513); // expected-error {{argument should be a value from -512 to 511}} Index: lib/Sema/SemaChecking.cpp === --- lib/Sema/SemaChecking.cpp +++ lib/Sema/SemaChecking.cpp @@ -1640,7 +1640,7 @@ case Mips::BI__builtin_msa_sldi_d: i = 2; l = 0; u = 1; break; // Memory offsets and immediate loads. // These intrinsics take a signed 10 bit immediate. - case Mips::BI__builtin_msa_ldi_b: i = 0; l = -128; u = 127; break; + case Mips::BI__builtin_msa_ldi_b: i = 0; l = -128; u = 255; break; case Mips::BI__builtin_msa_ldi_h: case Mips::BI__builtin_msa_ldi_w: case Mips::BI__builtin_msa_ldi_d: i = 0; l = -512; u = 511; break; Index: test/CodeGen/builtins-mips-msa-error.c === --- test/CodeGen/builtins-mips-msa-error.c +++ test/CodeGen/builtins-mips-msa-error.c @@ -119,7 +119,7 @@ v4i32_r = __msa_ld_w(&v4i32_a, 512); // expected-error {{argument should be a value from -512 to 511}} v2i64_r = __msa_ld_d(&v2i64_a, 512); // expected-error {{argument should be a value from -512 to 511}} - v16i8_r = __msa_ldi_b(512);// expected-error {{argument should be a value from -512 to 511}} + v16i8_r = __msa_ldi_b(256);// expected-error {{argument should be a value from -128 to 255}} v8i16_r = __msa_ldi_h(512);// expected-error {{argument should be a value from -512 to 511}} v4i32_r = __msa_ldi_w(512);// expected-error {{argument should be a value from -512 to 511}} v2i64_r = __msa_ldi_d(512);// expected-error {{argument should be a value from -512 to 511}} @@ -310,7 +310,7 @@ v4i32_r = __msa_ld_w(&v4i32_a, -513); // expected-error {{argument should be a value from -512 to 511}} v2i64_r = __msa_ld_d(&v2i64_a, -513); // expected-error {{argument should be a value from -512 to 511}} - v16i8_r = __msa_ldi_b(-513); // expected-error {{argument should be a value from -512 to 511}} + v16i8_r = __msa_ldi_b(-129); // expected-error {{argument should be a value from -128 to 255}} v8i16_r = __msa_ldi_h(-513); // expected-error {{argument should be a value from -512 to 511}} v4i32_r = __msa_ldi_w(-513); // expected-error {{argument should be a value from -512 to 511}} v2i64_r = __msa_ldi_d(-513); // expected-error {{argument should be a value from
[PATCH] D31076: [change-namespace] do not rename specialized template parameters.
This revision was automatically updated to reflect the committed changes. Closed by commit rL298090: [change-namespace] do not rename specialized template parameters. (authored by ioeric). Changed prior to commit: https://reviews.llvm.org/D31076?vs=92135&id=92141#toc Repository: rL LLVM https://reviews.llvm.org/D31076 Files: clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp Index: clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp === --- clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp +++ clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp @@ -286,6 +286,15 @@ return Node.isScoped(); } +bool isTemplateParameter(TypeLoc Type) { + while (!Type.isNull()) { +if (Type.getTypeLocClass() == TypeLoc::SubstTemplateTypeParm) + return true; +Type = Type.getNextTypeLoc(); + } + return false; +} + } // anonymous namespace ChangeNamespaceTool::ChangeNamespaceTool( @@ -833,6 +842,8 @@ // Types of CXXCtorInitializers do not need to be fixed. if (llvm::is_contained(BaseCtorInitializerTypeLocs, Type)) return; + if (isTemplateParameter(Type)) +return; // The declaration which this TypeLoc refers to. const auto *FromDecl = Result.Nodes.getNodeAs("from_decl"); // `hasDeclaration` gives underlying declaration, but if the type is Index: clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp === --- clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp +++ clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp @@ -2006,6 +2006,52 @@ EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); } +TEST_F(ChangeNamespaceTest, TypeAsTemplateParameter) { + std::string Code = "namespace na {\n" + "struct X {};\n" + "namespace nb {\n" + "template \n" + "void TempTemp(const TT& t) {\n" + " TT tmp;\n" + "}\n" + "template \n" + "void Temp(const T& t) {\n" + " T tmp = t;\n" + " TempTemp(tmp);\n" + " TempTemp(t);\n" + "}\n" + "void f() {\n" + " X x;\n" + " Temp(x);\n" + "}\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "namespace na {\n" + "struct X {};\n" + "\n" + "} // namespace na\n" + "namespace x {\n" + "namespace y {\n" + "template \n" + "void TempTemp(const TT& t) {\n" + " TT tmp;\n" + "}\n" + "template \n" + "void Temp(const T& t) {\n" + " T tmp = t;\n" + " TempTemp(tmp);\n" + " TempTemp(t);\n" + "}\n" + "void f() {\n" + " ::na::X x;\n" + " Temp(x);\n" + "}\n" + "} // namespace y\n" + "} // namespace x\n"; + + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + } // anonymous namespace } // namespace change_namespace } // namespace clang Index: clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp === --- clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp +++ clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp @@ -286,6 +286,15 @@ return Node.isScoped(); } +bool isTemplateParameter(TypeLoc Type) { + while (!Type.isNull()) { +if (Type.getTypeLocClass() == TypeLoc::SubstTemplateTypeParm) + return true; +Type = Type.getNextTypeLoc(); + } + return false; +} + } // anonymous namespace ChangeNamespaceTool::ChangeNamespaceTool( @@ -833,6 +842,8 @@ // Types of CXXCtorInitializers do not need to be fixed. if (llvm::is_contained(BaseCtorInitializerTypeLocs, Type)) return; + if (isTemplateParameter(Type)) +return; // The declaration which this TypeLoc refers to. const auto *FromDecl = Result.Nodes.getNodeAs("from_decl"); // `hasDeclaration` gives underlying declaration, but if the type is Index: clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp === --- clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp
[clang-tools-extra] r298090 - [change-namespace] do not rename specialized template parameters.
Author: ioeric Date: Fri Mar 17 09:05:39 2017 New Revision: 298090 URL: http://llvm.org/viewvc/llvm-project?rev=298090&view=rev Log: [change-namespace] do not rename specialized template parameters. Reviewers: hokein Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D31076 Modified: clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp Modified: clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp?rev=298090&r1=298089&r2=298090&view=diff == --- clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp (original) +++ clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp Fri Mar 17 09:05:39 2017 @@ -286,6 +286,15 @@ AST_MATCHER(EnumDecl, isScoped) { return Node.isScoped(); } +bool isTemplateParameter(TypeLoc Type) { + while (!Type.isNull()) { +if (Type.getTypeLocClass() == TypeLoc::SubstTemplateTypeParm) + return true; +Type = Type.getNextTypeLoc(); + } + return false; +} + } // anonymous namespace ChangeNamespaceTool::ChangeNamespaceTool( @@ -833,6 +842,8 @@ void ChangeNamespaceTool::fixTypeLoc( // Types of CXXCtorInitializers do not need to be fixed. if (llvm::is_contained(BaseCtorInitializerTypeLocs, Type)) return; + if (isTemplateParameter(Type)) +return; // The declaration which this TypeLoc refers to. const auto *FromDecl = Result.Nodes.getNodeAs("from_decl"); // `hasDeclaration` gives underlying declaration, but if the type is Modified: clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp?rev=298090&r1=298089&r2=298090&view=diff == --- clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp (original) +++ clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp Fri Mar 17 09:05:39 2017 @@ -2006,6 +2006,52 @@ TEST_F(ChangeNamespaceTest, EnumInClass) EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); } +TEST_F(ChangeNamespaceTest, TypeAsTemplateParameter) { + std::string Code = "namespace na {\n" + "struct X {};\n" + "namespace nb {\n" + "template \n" + "void TempTemp(const TT& t) {\n" + " TT tmp;\n" + "}\n" + "template \n" + "void Temp(const T& t) {\n" + " T tmp = t;\n" + " TempTemp(tmp);\n" + " TempTemp(t);\n" + "}\n" + "void f() {\n" + " X x;\n" + " Temp(x);\n" + "}\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "namespace na {\n" + "struct X {};\n" + "\n" + "} // namespace na\n" + "namespace x {\n" + "namespace y {\n" + "template \n" + "void TempTemp(const TT& t) {\n" + " TT tmp;\n" + "}\n" + "template \n" + "void Temp(const T& t) {\n" + " T tmp = t;\n" + " TempTemp(tmp);\n" + " TempTemp(t);\n" + "}\n" + "void f() {\n" + " ::na::X x;\n" + " Temp(x);\n" + "}\n" + "} // namespace y\n" + "} // namespace x\n"; + + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + } // anonymous namespace } // namespace change_namespace } // namespace clang ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31078: [libunwind] Clean up macro usage.
rs created this revision. Convention in libunwind is to use !defined(FOO) not !FOO. https://reviews.llvm.org/D31078 Files: include/__libunwind_config.h include/libunwind.h include/unwind.h src/AddressSpace.hpp src/Unwind-EHABI.cpp src/Unwind-EHABI.h src/Unwind-sjlj.c src/UnwindCursor.hpp src/UnwindLevel1-gcc-ext.c src/UnwindLevel1.c src/Unwind_AppleExtras.cpp src/config.h src/libunwind.cpp src/libunwind_ext.h Index: src/libunwind_ext.h === --- src/libunwind_ext.h +++ src/libunwind_ext.h @@ -33,7 +33,7 @@ extern void _unw_add_dynamic_fde(unw_word_t fde); extern void _unw_remove_dynamic_fde(unw_word_t fde); -#if _LIBUNWIND_ARM_EHABI +#if defined(_LIBUNWIND_ARM_EHABI) extern const uint32_t* decode_eht_entry(const uint32_t*, size_t*, size_t*); extern _Unwind_Reason_Code _Unwind_VRS_Interpret(_Unwind_Context *context, const uint32_t *data, Index: src/libunwind.cpp === --- src/libunwind.cpp +++ src/libunwind.cpp @@ -54,7 +54,7 @@ # define REGISTER_KIND Registers_ppc #elif defined(__aarch64__) # define REGISTER_KIND Registers_arm64 -#elif _LIBUNWIND_ARM_EHABI +#elif defined(_LIBUNWIND_ARM_EHABI) # define REGISTER_KIND Registers_arm #elif defined(__or1k__) # define REGISTER_KIND Registers_or1k @@ -207,7 +207,7 @@ /// Set value of specified float register at cursor position in stack frame. _LIBUNWIND_EXPORT int unw_set_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum, unw_fpreg_t value) { -#if _LIBUNWIND_ARM_EHABI +#if defined(_LIBUNWIND_ARM_EHABI) _LIBUNWIND_TRACE_API("unw_set_fpreg(cursor=%p, regNum=%d, value=%llX)", static_cast(cursor), regNum, value); #else @@ -306,7 +306,7 @@ #endif -#if _LIBUNWIND_SUPPORT_DWARF_UNWIND +#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) /// SPI: walks cached DWARF entries _LIBUNWIND_EXPORT void unw_iterate_dwarf_unwind_cache(void (*func)( unw_word_t ip_start, unw_word_t ip_end, unw_word_t fde, unw_word_t mh)) { @@ -340,7 +340,7 @@ // fde is own mh_group DwarfFDECache::removeAllIn((LocalAddressSpace::pint_t)fde); } -#endif // _LIBUNWIND_SUPPORT_DWARF_UNWIND +#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) Index: src/config.h === --- src/config.h +++ src/config.h @@ -33,22 +33,14 @@ #ifdef __APPLE__ #if defined(FOR_DYLD) #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 1 -#define _LIBUNWIND_SUPPORT_DWARF_UNWIND 0 -#define _LIBUNWIND_SUPPORT_DWARF_INDEX0 #else #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 1 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1 -#define _LIBUNWIND_SUPPORT_DWARF_INDEX0 #endif #else #if defined(__ARM_DWARF_EH__) || !defined(__arm__) -#define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 0 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1 #define _LIBUNWIND_SUPPORT_DWARF_INDEX 1 - #else -#define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 0 -#define _LIBUNWIND_SUPPORT_DWARF_UNWIND 0 -#define _LIBUNWIND_SUPPORT_DWARF_INDEX 0 #endif #endif @@ -58,24 +50,18 @@ #if (defined(__APPLE__) && defined(__arm__)) || defined(__USING_SJLJ_EXCEPTIONS__) #define _LIBUNWIND_BUILD_SJLJ_APIS 1 -#else -#define _LIBUNWIND_BUILD_SJLJ_APIS 0 #endif #if defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || defined(__ppc64__) #define _LIBUNWIND_SUPPORT_FRAME_APIS 1 -#else -#define _LIBUNWIND_SUPPORT_FRAME_APIS 0 #endif #if defined(__i386__) || defined(__x86_64__) ||\ defined(__ppc__) || defined(__ppc64__) || \ (!defined(__APPLE__) && defined(__arm__)) || \ (defined(__arm64__) || defined(__aarch64__)) ||\ (defined(__APPLE__) && defined(__mips__)) #define _LIBUNWIND_BUILD_ZERO_COST_APIS 1 -#else -#define _LIBUNWIND_BUILD_ZERO_COST_APIS 0 #endif #if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL) Index: src/Unwind_AppleExtras.cpp === --- src/Unwind_AppleExtras.cpp +++ src/Unwind_AppleExtras.cpp @@ -77,7 +77,7 @@ #endif -#if _LIBUNWIND_BUILD_ZERO_COST_APIS +#if defined(_LIBUNWIND_BUILD_ZERO_COST_APIS) // // symbols in libSystem.dylib in 10.6 and later, but are in libgcc_s.dylib in @@ -116,12 +116,12 @@ NEVER_HERE(__deregister_frame_info) NEVER_HERE(__deregister_frame_info_bases) -#endif // _LIBUNWIND_BUILD_ZERO_COST_APIS +#endif // defined(_LIBUNWIND_BUILD_ZERO_COST_APIS) -#if _LIBUNWIND_BUILD_SJLJ_APIS +#if defined(_LIBUNWIND_BUILD_SJLJ_APIS) // // symbols in libSystem.dylib in iOS 5.0 and later, but are in libgcc_s.dylib in // earlier versions @@ -141,7 +141,7 @@ NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Resume_or_Rethrow) NO
[PATCH] D31076: [change-namespace] do not rename specialized template parameters.
hokein accepted this revision. hokein added a comment. This revision is now accepted and ready to land. LGTM. https://reviews.llvm.org/D31076 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30493: [change-namespace] avoid adding leading '::' when possible.
ioeric updated this revision to Diff 92138. ioeric marked 3 inline comments as done. ioeric added a comment. - Merged with origin/master - Addressed comments. Merged with origin/master. https://reviews.llvm.org/D30493 Files: change-namespace/ChangeNamespace.cpp unittests/change-namespace/ChangeNamespaceTests.cpp Index: unittests/change-namespace/ChangeNamespaceTests.cpp === --- unittests/change-namespace/ChangeNamespaceTests.cpp +++ unittests/change-namespace/ChangeNamespaceTests.cpp @@ -242,7 +242,7 @@ "} // namespace na\n" "namespace x {\n" "namespace y {\n" - "class X { ::na::A a; z::Z zz; T t; };\n" + "class X { na::A a; z::Z zz; T t; };\n" "} // namespace y\n" "} // namespace x\n"; EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); @@ -296,8 +296,8 @@ "namespace y {\n" "class C_X {\n" "public:\n" - " ::na::C_A a;\n" - " ::na::nc::C_C c;\n" + " na::C_A a;\n" + " na::nc::C_C c;\n" "};\n" "class C_Y {\n" " C_X x;\n" @@ -339,9 +339,9 @@ "namespace x {\n" "namespace y {\n" "void f() {\n" - " ::na::B<::na::A> b;\n" - " ::na::B<::na::nc::C> b_c;\n" - " ::na::Two<::na::A, ::na::nc::C> two;\n" + " na::B b;\n" + " na::B b_c;\n" + " na::Two two;\n" "}\n" "} // namespace y\n" "} // namespace x\n"; @@ -368,7 +368,7 @@ "namespace y {\n" "\n" "class A {\n" - " ::na::nb::FWD *fwd;\n" + " na::nb::FWD *fwd;\n" "};\n" "} // namespace y\n" "} // namespace x\n"; @@ -397,7 +397,7 @@ "namespace y {\n" "\n" "class A {\n" - " ::na::nb::FWD *fwd;\n" + " na::nb::FWD *fwd;\n" "};\n" "\n" "} // namespace y\n" @@ -426,7 +426,7 @@ "namespace y {\n" "\n" "class A {\n" - " ::na::nb::FWD *fwd;\n" + " na::nb::FWD *fwd;\n" "};\n" "template class TEMP {};\n" "} // namespace y\n" @@ -481,8 +481,8 @@ "namespace x {\n" "namespace y {\n" "void fwd();\n" - "void f(::na::C_A ca, ::na::nc::C_C cc) {\n" - " ::na::C_A ca_1 = ca;\n" + "void f(na::C_A ca, na::nc::C_C cc) {\n" + " na::C_A ca_1 = ca;\n" "}\n" "} // namespace y\n" "} // namespace x\n"; @@ -521,9 +521,9 @@ "namespace x {\n" "namespace y {\n" "using ::na::nc::SAME;\n" - "using YO = ::na::nd::SAME;\n" - "typedef ::na::nd::SAME IDENTICAL;\n" - "void f(::na::nd::SAME Same) {}\n" + "using YO = na::nd::SAME;\n" + "typedef na::nd::SAME IDENTICAL;\n" + "void f(na::nd::SAME Same) {}\n" "} // namespace y\n" "} // namespace x\n"; EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); @@ -549,9 +549,9 @@ "} // namespace na\n" "namespace x {\n" "namespace y {\n" - "class D : public ::na::Base {\n" + "class D : public na::Base {\n" "public:\n" - " using AA = ::na::A; using B = ::na::Base;\n" + " using AA = na::A; using B = na::Base;\n" " using Base::m; using Base::Base;\n" "};" "} // namespace y\n" @@ -596,11 +596,11 @@ "namespace x {\n" "namespace y {\n" "cla
[PATCH] D30493: [change-namespace] avoid adding leading '::' when possible.
ioeric added inline comments. Comment at: change-namespace/ChangeNamespace.cpp:291 + assert(!SymbolSplitted.empty()); + SymbolSplitted.pop_back(); + hokein wrote: > Is this needed? Looks like you are removing the name of the symbol here, but > from the code below, you only use the first element of it. The > QualifiedSymbol should always be a fully-qualified name with at least 1 > namespace qualifier in the code, right? `QualifiedSymbol` can be in the global namespace, so `SymbolSplitted` could be empty after `pop_back`. Comment at: change-namespace/ChangeNamespace.cpp:296 +assert(!NsSplitted.empty()); +for (auto I = NsSplitted.begin() + 1, E = NsSplitted.end(); I != E; ++I) { + if (*I == SymbolSplitted.front()) hokein wrote: > Why skipping the first element? And use `is_contained` instead? See newly added comments for reasoning. https://reviews.llvm.org/D30493 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31049: [Clang-tidy] Fix for misc-noexcept-move-constructor false triggers on defaulted declarations
edyp87 added a comment. No, please apply this patch for me. Thank you! Repository: rL LLVM https://reviews.llvm.org/D31049 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31076: [change-namespace] do not rename specialized template parameters.
ioeric created this revision. https://reviews.llvm.org/D31076 Files: change-namespace/ChangeNamespace.cpp unittests/change-namespace/ChangeNamespaceTests.cpp Index: unittests/change-namespace/ChangeNamespaceTests.cpp === --- unittests/change-namespace/ChangeNamespaceTests.cpp +++ unittests/change-namespace/ChangeNamespaceTests.cpp @@ -2006,6 +2006,52 @@ EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); } +TEST_F(ChangeNamespaceTest, TypeAsTemplateParameter) { + std::string Code = "namespace na {\n" + "struct X {};\n" + "namespace nb {\n" + "template \n" + "void TempTemp(const TT& t) {\n" + " TT tmp;\n" + "}\n" + "template \n" + "void Temp(const T& t) {\n" + " T tmp = t;\n" + " TempTemp(tmp);\n" + " TempTemp(t);\n" + "}\n" + "void f() {\n" + " X x;\n" + " Temp(x);\n" + "}\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "namespace na {\n" + "struct X {};\n" + "\n" + "} // namespace na\n" + "namespace x {\n" + "namespace y {\n" + "template \n" + "void TempTemp(const TT& t) {\n" + " TT tmp;\n" + "}\n" + "template \n" + "void Temp(const T& t) {\n" + " T tmp = t;\n" + " TempTemp(tmp);\n" + " TempTemp(t);\n" + "}\n" + "void f() {\n" + " ::na::X x;\n" + " Temp(x);\n" + "}\n" + "} // namespace y\n" + "} // namespace x\n"; + + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + } // anonymous namespace } // namespace change_namespace } // namespace clang Index: change-namespace/ChangeNamespace.cpp === --- change-namespace/ChangeNamespace.cpp +++ change-namespace/ChangeNamespace.cpp @@ -286,6 +286,15 @@ return Node.isScoped(); } +bool isTemplateParameter(TypeLoc Type) { + while (!Type.isNull()) { +if (Type.getTypeLocClass() == TypeLoc::SubstTemplateTypeParm) + return true; +Type = Type.getNextTypeLoc(); + } + return false; +} + } // anonymous namespace ChangeNamespaceTool::ChangeNamespaceTool( @@ -833,6 +842,8 @@ // Types of CXXCtorInitializers do not need to be fixed. if (llvm::is_contained(BaseCtorInitializerTypeLocs, Type)) return; + if (isTemplateParameter(Type)) +return; // The declaration which this TypeLoc refers to. const auto *FromDecl = Result.Nodes.getNodeAs("from_decl"); // `hasDeclaration` gives underlying declaration, but if the type is Index: unittests/change-namespace/ChangeNamespaceTests.cpp === --- unittests/change-namespace/ChangeNamespaceTests.cpp +++ unittests/change-namespace/ChangeNamespaceTests.cpp @@ -2006,6 +2006,52 @@ EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); } +TEST_F(ChangeNamespaceTest, TypeAsTemplateParameter) { + std::string Code = "namespace na {\n" + "struct X {};\n" + "namespace nb {\n" + "template \n" + "void TempTemp(const TT& t) {\n" + " TT tmp;\n" + "}\n" + "template \n" + "void Temp(const T& t) {\n" + " T tmp = t;\n" + " TempTemp(tmp);\n" + " TempTemp(t);\n" + "}\n" + "void f() {\n" + " X x;\n" + " Temp(x);\n" + "}\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "namespace na {\n" + "struct X {};\n" + "\n" + "} // namespace na\n" + "namespace x {\n" + "namespace y {\n" + "template \n" + "void TempTemp(const TT& t) {\n" + " TT tmp;\n" + "}\n" + "template \n" + "void Temp(const T& t) {\n" + " T tmp = t;\n" +
[PATCH] D31049: [Clang-tidy] Fix for misc-noexcept-move-constructor false triggers on defaulted declarations
alexfh added a comment. Do you have commit rights? Repository: rL LLVM https://reviews.llvm.org/D31049 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31049: [Clang-tidy] Fix for misc-noexcept-move-constructor false triggers on defaulted declarations
alexfh accepted this revision. alexfh added a comment. This revision is now accepted and ready to land. LG Repository: rL LLVM https://reviews.llvm.org/D31049 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31069: Don't warn about an unreachable fallthrough annotation in a template function
ahmedasadi added a comment. Thanks for reviewing. Yes, I need someone to commit for me. https://reviews.llvm.org/D31069 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30415: Fix -mno-altivec cannot overwrite -maltivec option
uweigand added a comment. In https://reviews.llvm.org/D30415#703442, @hfinkel wrote: > In https://reviews.llvm.org/D30415#703398, @echristo wrote: > > > Different suggestion: > > > > Remove the faltivec option. Even gcc doesn't support it anymore afaict. > > > What are you suggesting? Always having the language extensions on? Or > explicitly tying the language extensions to the underlying target feature? I'm a bit confused by this discussion. -faltivec and -maltivec are simply aliases, they do exactly the same thing; the clang-internal variable OPT_faltivec indicates the use of either -faltivec or -maltivec. Is the suggestion to remove that flag completely, i.e. both -maltivec and -faltivec? This seems strange to me since -maltivec is used in many Makefiles etc. that would break if clang suddenly refused to accept the option. Or is the suggestion to simply remove the alias -faltivec, and leave -maltivec as-is? I'd be less opposed to this since it probably breaks fewer users ... but I'm still not quite sure what it actually buys us. And in any case the patch currently under discussion here would still be necessary then, to fix -maltivec -mno-altivec ... https://reviews.llvm.org/D30415 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r298060 - [clang-tidy] Added a test with a different format.
Author: alexfh Date: Fri Mar 17 05:05:49 2017 New Revision: 298060 URL: http://llvm.org/viewvc/llvm-project?rev=298060&view=rev Log: [clang-tidy] Added a test with a different format. Modified: clang-tools-extra/trunk/test/clang-tidy/readability-misleading-indentation.cpp Modified: clang-tools-extra/trunk/test/clang-tidy/readability-misleading-indentation.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/readability-misleading-indentation.cpp?rev=298060&r1=298059&r2=298060&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/readability-misleading-indentation.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/readability-misleading-indentation.cpp Fri Mar 17 05:05:49 2017 @@ -98,6 +98,11 @@ int main() } else { } +if (cond1) { +} else if (cond2) { +} else if (!cond2) { +} else { +} } else if (cond2) { } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30841: [clang-tidy] readability-misleading-indentation: fix chained if
This revision was automatically updated to reflect the committed changes. Closed by commit rL298059: [clang-tidy] readability-misleading-indentation: fix chained if (authored by alexfh). Changed prior to commit: https://reviews.llvm.org/D30841?vs=92026&id=92116#toc Repository: rL LLVM https://reviews.llvm.org/D30841 Files: clang-tools-extra/trunk/clang-tidy/readability/MisleadingIndentationCheck.cpp clang-tools-extra/trunk/clang-tidy/readability/MisleadingIndentationCheck.h clang-tools-extra/trunk/test/clang-tidy/readability-misleading-indentation.cpp Index: clang-tools-extra/trunk/clang-tidy/readability/MisleadingIndentationCheck.h === --- clang-tools-extra/trunk/clang-tidy/readability/MisleadingIndentationCheck.h +++ clang-tools-extra/trunk/clang-tidy/readability/MisleadingIndentationCheck.h @@ -30,7 +30,8 @@ void check(const ast_matchers::MatchFinder::MatchResult &Result) override; private: - void danglingElseCheck(const SourceManager &SM, const IfStmt *If); + void danglingElseCheck(const SourceManager &SM, ASTContext *Context, + const IfStmt *If); void missingBracesCheck(const SourceManager &SM, const CompoundStmt *CStmt); }; Index: clang-tools-extra/trunk/clang-tidy/readability/MisleadingIndentationCheck.cpp === --- clang-tools-extra/trunk/clang-tidy/readability/MisleadingIndentationCheck.cpp +++ clang-tools-extra/trunk/clang-tidy/readability/MisleadingIndentationCheck.cpp @@ -17,7 +17,22 @@ namespace tidy { namespace readability { +static const IfStmt *getPrecedingIf(const SourceManager &SM, +ASTContext *Context, const IfStmt *If) { + auto parents = Context->getParents(*If); + if (parents.size() != 1) +return nullptr; + if (const auto *PrecedingIf = parents[0].get()) { +SourceLocation PreviousElseLoc = PrecedingIf->getElseLoc(); +if (SM.getExpansionLineNumber(PreviousElseLoc) == +SM.getExpansionLineNumber(If->getIfLoc())) + return PrecedingIf; + } + return nullptr; +} + void MisleadingIndentationCheck::danglingElseCheck(const SourceManager &SM, + ASTContext *Context, const IfStmt *If) { SourceLocation IfLoc = If->getIfLoc(); SourceLocation ElseLoc = If->getElseLoc(); @@ -29,6 +44,11 @@ SM.getExpansionLineNumber(ElseLoc)) return; + // Find location of first 'if' in a 'if else if' chain. + for (auto PrecedingIf = getPrecedingIf(SM, Context, If); PrecedingIf; + PrecedingIf = getPrecedingIf(SM, Context, PrecedingIf)) +IfLoc = PrecedingIf->getIfLoc(); + if (SM.getExpansionColumnNumber(IfLoc) != SM.getExpansionColumnNumber(ElseLoc)) diag(ElseLoc, "different indentation for 'if' and corresponding 'else'"); @@ -92,7 +112,7 @@ void MisleadingIndentationCheck::check(const MatchFinder::MatchResult &Result) { if (const auto *If = Result.Nodes.getNodeAs("if")) -danglingElseCheck(*Result.SourceManager, If); +danglingElseCheck(*Result.SourceManager, Result.Context, If); if (const auto *CStmt = Result.Nodes.getNodeAs("compound")) missingBracesCheck(*Result.SourceManager, CStmt); Index: clang-tools-extra/trunk/test/clang-tidy/readability-misleading-indentation.cpp === --- clang-tools-extra/trunk/test/clang-tidy/readability-misleading-indentation.cpp +++ clang-tools-extra/trunk/test/clang-tidy/readability-misleading-indentation.cpp @@ -76,5 +76,31 @@ { } + if(cond1) { + } + else if (cond2) { + } + else { + } + + if(cond1) { + } + else if (cond2) { + } + else { + } + // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: different indentation for 'if' and corresponding 'else' [readability-misleading-indentation] + + if (cond1) { +if (cond1) { +} +else if (cond2) { +} +else { +} + } + else if (cond2) { + } + BLOCK } Index: clang-tools-extra/trunk/clang-tidy/readability/MisleadingIndentationCheck.h === --- clang-tools-extra/trunk/clang-tidy/readability/MisleadingIndentationCheck.h +++ clang-tools-extra/trunk/clang-tidy/readability/MisleadingIndentationCheck.h @@ -30,7 +30,8 @@ void check(const ast_matchers::MatchFinder::MatchResult &Result) override; private: - void danglingElseCheck(const SourceManager &SM, const IfStmt *If); + void danglingElseCheck(const SourceManager &SM, ASTContext *Context, + const IfStmt *If); void missingBracesCheck(const SourceManager &SM, const CompoundStmt *CStmt); }; Index: clang-tools-extra/trunk/clang-tidy/readability/MisleadingIndentationCheck.cpp === --- clang-tools-extra/trunk/cla
[clang-tools-extra] r298059 - [clang-tidy] readability-misleading-indentation: fix chained if
Author: alexfh Date: Fri Mar 17 04:58:30 2017 New Revision: 298059 URL: http://llvm.org/viewvc/llvm-project?rev=298059&view=rev Log: [clang-tidy] readability-misleading-indentation: fix chained if Summary: Fixed erroneously flagging of chained if statements when styled like this: ``` if (cond) { } else if (cond) { } else { } ``` Reviewers: xazax.hun, alexfh Reviewed By: xazax.hun, alexfh Subscribers: JDevlieghere, cfe-commits Patch by Florian Gross! Differential Revision: https://reviews.llvm.org/D30841 Modified: clang-tools-extra/trunk/clang-tidy/readability/MisleadingIndentationCheck.cpp clang-tools-extra/trunk/clang-tidy/readability/MisleadingIndentationCheck.h clang-tools-extra/trunk/test/clang-tidy/readability-misleading-indentation.cpp Modified: clang-tools-extra/trunk/clang-tidy/readability/MisleadingIndentationCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/readability/MisleadingIndentationCheck.cpp?rev=298059&r1=298058&r2=298059&view=diff == --- clang-tools-extra/trunk/clang-tidy/readability/MisleadingIndentationCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/readability/MisleadingIndentationCheck.cpp Fri Mar 17 04:58:30 2017 @@ -17,7 +17,22 @@ namespace clang { namespace tidy { namespace readability { +static const IfStmt *getPrecedingIf(const SourceManager &SM, +ASTContext *Context, const IfStmt *If) { + auto parents = Context->getParents(*If); + if (parents.size() != 1) +return nullptr; + if (const auto *PrecedingIf = parents[0].get()) { +SourceLocation PreviousElseLoc = PrecedingIf->getElseLoc(); +if (SM.getExpansionLineNumber(PreviousElseLoc) == +SM.getExpansionLineNumber(If->getIfLoc())) + return PrecedingIf; + } + return nullptr; +} + void MisleadingIndentationCheck::danglingElseCheck(const SourceManager &SM, + ASTContext *Context, const IfStmt *If) { SourceLocation IfLoc = If->getIfLoc(); SourceLocation ElseLoc = If->getElseLoc(); @@ -29,6 +44,11 @@ void MisleadingIndentationCheck::danglin SM.getExpansionLineNumber(ElseLoc)) return; + // Find location of first 'if' in a 'if else if' chain. + for (auto PrecedingIf = getPrecedingIf(SM, Context, If); PrecedingIf; + PrecedingIf = getPrecedingIf(SM, Context, PrecedingIf)) +IfLoc = PrecedingIf->getIfLoc(); + if (SM.getExpansionColumnNumber(IfLoc) != SM.getExpansionColumnNumber(ElseLoc)) diag(ElseLoc, "different indentation for 'if' and corresponding 'else'"); @@ -92,7 +112,7 @@ void MisleadingIndentationCheck::registe void MisleadingIndentationCheck::check(const MatchFinder::MatchResult &Result) { if (const auto *If = Result.Nodes.getNodeAs("if")) -danglingElseCheck(*Result.SourceManager, If); +danglingElseCheck(*Result.SourceManager, Result.Context, If); if (const auto *CStmt = Result.Nodes.getNodeAs("compound")) missingBracesCheck(*Result.SourceManager, CStmt); Modified: clang-tools-extra/trunk/clang-tidy/readability/MisleadingIndentationCheck.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/readability/MisleadingIndentationCheck.h?rev=298059&r1=298058&r2=298059&view=diff == --- clang-tools-extra/trunk/clang-tidy/readability/MisleadingIndentationCheck.h (original) +++ clang-tools-extra/trunk/clang-tidy/readability/MisleadingIndentationCheck.h Fri Mar 17 04:58:30 2017 @@ -30,7 +30,8 @@ public: void check(const ast_matchers::MatchFinder::MatchResult &Result) override; private: - void danglingElseCheck(const SourceManager &SM, const IfStmt *If); + void danglingElseCheck(const SourceManager &SM, ASTContext *Context, + const IfStmt *If); void missingBracesCheck(const SourceManager &SM, const CompoundStmt *CStmt); }; Modified: clang-tools-extra/trunk/test/clang-tidy/readability-misleading-indentation.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/readability-misleading-indentation.cpp?rev=298059&r1=298058&r2=298059&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/readability-misleading-indentation.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/readability-misleading-indentation.cpp Fri Mar 17 04:58:30 2017 @@ -76,5 +76,31 @@ int main() { } + if(cond1) { + } + else if (cond2) { + } + else { + } + + if(cond1) { + } + else if (cond2) { + } + else { + } + // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: different indentation for 'if' and corresponding 'else' [readability-misleading-indentation] + + if (cond1) { +if (cond1) { +} +else if
[PATCH] D26350: Keep invalid Switch in the AST
ogoffart added a comment. Ping https://reviews.llvm.org/D26350 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r298057 - [clang-tidy] Verify some conditions in a matcher instead of check(). NFC
Author: alexfh Date: Fri Mar 17 04:47:05 2017 New Revision: 298057 URL: http://llvm.org/viewvc/llvm-project?rev=298057&view=rev Log: [clang-tidy] Verify some conditions in a matcher instead of check(). NFC Modified: clang-tools-extra/trunk/clang-tidy/google/ExplicitConstructorCheck.cpp Modified: clang-tools-extra/trunk/clang-tidy/google/ExplicitConstructorCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/google/ExplicitConstructorCheck.cpp?rev=298057&r1=298056&r2=298057&view=diff == --- clang-tools-extra/trunk/clang-tidy/google/ExplicitConstructorCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/google/ExplicitConstructorCheck.cpp Fri Mar 17 04:47:05 2017 @@ -24,8 +24,11 @@ void ExplicitConstructorCheck::registerM // provide any benefit to other languages, despite being benign. if (!getLangOpts().CPlusPlus) return; - Finder->addMatcher(cxxConstructorDecl(unless(isInstantiated())).bind("ctor"), - this); + Finder->addMatcher( + cxxConstructorDecl(unless(anyOf(isImplicit(), // Compiler-generated. + isDeleted(), isInstantiated( + .bind("ctor"), + this); Finder->addMatcher( cxxConversionDecl(unless(anyOf(isExplicit(), // Already marked explicit. isImplicit(), // Compiler-generated. @@ -99,10 +102,8 @@ void ExplicitConstructorCheck::check(con } const auto *Ctor = Result.Nodes.getNodeAs("ctor"); - // Do not be confused: isExplicit means 'explicit' keyword is present, - // isImplicit means that it's a compiler-generated constructor. - if (Ctor->isOutOfLine() || Ctor->isImplicit() || Ctor->isDeleted() || - Ctor->getNumParams() == 0 || Ctor->getMinRequiredArguments() > 1) + if (Ctor->isOutOfLine() || Ctor->getNumParams() == 0 || + Ctor->getMinRequiredArguments() > 1) return; bool takesInitializerList = isStdInitializerList( ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30841: [clang-tidy] readability-misleading-indentation: fix chained if
alexfh accepted this revision. alexfh added a comment. This revision is now accepted and ready to land. In https://reviews.llvm.org/D30841#702980, @fgross wrote: > Now using `ASTContext::getParents` instead of `ChainedIfs` map. > > For some reason I thought of `getParents` as an expensive function to call... Good point. It is expensive first time you call it, since it builds parents map. My idea was that since many checks use hasParent or hasAncestor matchers, the parent map will likely be built anyway, and building a (smaller) map of chained `if`s as an optimization won't make much difference. But I don't know for sure, and maybe your approach is indeed better. We can start with the parent-map based one and keep the possible optimization in mind, in case there's an evidence of performance issues. LG. I'll submit the patch for you. https://reviews.llvm.org/D30841 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30931: [clang-tidy] modified identifier naming case to use CT_AnyCase for ignoring case style
jutocz updated this revision to Diff 92108. jutocz retitled this revision from "[clang-tidy] added new identifier naming case type for ignoring case style" to "[clang-tidy] modified identifier naming case to use CT_AnyCase for ignoring case style". jutocz edited the summary of this revision. jutocz added a comment. I've modified patch to use llvm::Optional for not defined naming style and naming case. I had to use llvm::Optional in two places: - for entries in collection of naming styles (IdentifierNamingCheck::NamingStyles) where style for specific identifier was not set (more general style will be used in this case) - for case type in NamingStyle, where case style was not set but prefix or postfix was (this remains a bit unintuitive, bacause case style will be ignored and only prefix or postfix will get validated) https://reviews.llvm.org/D30931 Files: clang-tidy/readability/IdentifierNamingCheck.cpp clang-tidy/readability/IdentifierNamingCheck.h Index: clang-tidy/readability/IdentifierNamingCheck.h === --- clang-tidy/readability/IdentifierNamingCheck.h +++ clang-tidy/readability/IdentifierNamingCheck.h @@ -53,19 +53,16 @@ }; struct NamingStyle { -NamingStyle() : Case(CT_AnyCase) {} +NamingStyle() = default; -NamingStyle(CaseType Case, const std::string &Prefix, +NamingStyle(llvm::Optional Case, +const std::string &Prefix, const std::string &Suffix) : Case(Case), Prefix(Prefix), Suffix(Suffix) {} -CaseType Case; +llvm::Optional Case; std::string Prefix; std::string Suffix; - -bool isSet() const { - return !(Case == CT_AnyCase && Prefix.empty() && Suffix.empty()); -} }; /// \brief Holds an identifier name check failure, tracking the kind of the @@ -101,7 +98,7 @@ void expandMacro(const Token &MacroNameTok, const MacroInfo *MI); private: - std::vector NamingStyles; + std::vector > NamingStyles; bool IgnoreFailedSplit; NamingCheckFailureMap NamingCheckFailures; }; Index: clang-tidy/readability/IdentifierNamingCheck.cpp === --- clang-tidy/readability/IdentifierNamingCheck.cpp +++ clang-tidy/readability/IdentifierNamingCheck.cpp @@ -158,21 +158,28 @@ ClangTidyContext *Context) : ClangTidyCheck(Name, Context) { auto const fromString = [](StringRef Str) { -return llvm::StringSwitch(Str) +return llvm::StringSwitch >(Str) +.Case("aNy_CasE", CT_AnyCase) .Case("lower_case", CT_LowerCase) .Case("UPPER_CASE", CT_UpperCase) .Case("camelBack", CT_CamelBack) .Case("CamelCase", CT_CamelCase) .Case("Camel_Snake_Case", CT_CamelSnakeCase) .Case("camel_Snake_Back", CT_CamelSnakeBack) -.Default(CT_AnyCase); +.Default(llvm::Optional()); }; for (auto const &Name : StyleNames) { -NamingStyles.push_back( -NamingStyle(fromString(Options.get((Name + "Case").str(), "")), -Options.get((Name + "Prefix").str(), ""), -Options.get((Name + "Suffix").str(), ""))); +auto const caseOptional = +fromString(Options.get((Name + "Case").str(), "")); +auto prefix = Options.get((Name + "Prefix").str(), ""); +auto postfix = Options.get((Name + "Suffix").str(), ""); + +if (caseOptional.hasValue() || !prefix.empty() || !postfix.empty()) { + NamingStyles.push_back(NamingStyle(caseOptional, prefix, postfix)); +} else { + NamingStyles.push_back(llvm::Optional()); +} } IgnoreFailedSplit = Options.get("IgnoreFailedSplit", 0); @@ -201,12 +208,16 @@ }; for (size_t i = 0; i < SK_Count; ++i) { -Options.store(Opts, (StyleNames[i] + "Case").str(), - toString(NamingStyles[i].Case)); -Options.store(Opts, (StyleNames[i] + "Prefix").str(), - NamingStyles[i].Prefix); -Options.store(Opts, (StyleNames[i] + "Suffix").str(), - NamingStyles[i].Suffix); +if (NamingStyles[i].hasValue()) { + if (NamingStyles[i]->Case.hasValue()) { +Options.store(Opts, (StyleNames[i] + "Case").str(), + toString(NamingStyles[i]->Case.getValue())); + } + Options.store(Opts, (StyleNames[i] + "Prefix").str(), +NamingStyles[i]->Prefix); + Options.store(Opts, (StyleNames[i] + "Suffix").str(), +NamingStyles[i]->Suffix); +} } Options.store(Opts, "IgnoreFailedSplit", IgnoreFailedSplit); @@ -251,7 +262,8 @@ else Matches = false; - if (!Matchers[static_cast(Style.Case)].match(Name)) + if (Style.Case.hasValue() && + !Matchers[static_cast(Style.Case.getValue())].match(Name)) Matches = false; return Matches; @@ -354,38 +366,42 @@ } static std::string fixupWithStyle(StringRef Name, -
[clang-tools-extra] r298052 - [clang-tidy] Ignore deleted members in google-explicit-constructor.
Author: alexfh Date: Fri Mar 17 03:40:07 2017 New Revision: 298052 URL: http://llvm.org/viewvc/llvm-project?rev=298052&view=rev Log: [clang-tidy] Ignore deleted members in google-explicit-constructor. This fixes http://llvm.org/PR32221. Modified: clang-tools-extra/trunk/clang-tidy/google/ExplicitConstructorCheck.cpp clang-tools-extra/trunk/test/clang-tidy/google-explicit-constructor.cpp Modified: clang-tools-extra/trunk/clang-tidy/google/ExplicitConstructorCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/google/ExplicitConstructorCheck.cpp?rev=298052&r1=298051&r2=298052&view=diff == --- clang-tools-extra/trunk/clang-tidy/google/ExplicitConstructorCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/google/ExplicitConstructorCheck.cpp Fri Mar 17 03:40:07 2017 @@ -29,7 +29,7 @@ void ExplicitConstructorCheck::registerM Finder->addMatcher( cxxConversionDecl(unless(anyOf(isExplicit(), // Already marked explicit. isImplicit(), // Compiler-generated. - isInstantiated( + isDeleted(), isInstantiated( .bind("conversion"), this); Modified: clang-tools-extra/trunk/test/clang-tidy/google-explicit-constructor.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/google-explicit-constructor.cpp?rev=298052&r1=298051&r2=298052&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/google-explicit-constructor.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/google-explicit-constructor.cpp Fri Mar 17 03:40:07 2017 @@ -40,6 +40,8 @@ struct A { explicit A(void *x, void *y) {} explicit operator bool() const { return true; } + operator double() const = delete; + explicit A(const A& a) {} // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: copy constructor should not be declared explicit [google-explicit-constructor] // CHECK-FIXES: {{^ }}A(const A& a) {} ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits