[PATCH] D38921: [analyzer] LoopUnrolling: update the matched assignment operators
szepet updated this revision to Diff 120732. szepet added a comment. Updated to use a custom AST matcher for assignment operator check. (More structured and efficient.) https://reviews.llvm.org/D38921 Files: lib/StaticAnalyzer/Core/LoopUnrolling.cpp test/Analysis/loop-unrolling.cpp Index: test/Analysis/loop-unrolling.cpp === --- test/Analysis/loop-unrolling.cpp +++ test/Analysis/loop-unrolling.cpp @@ -98,13 +98,101 @@ return 0; } +int no_unroll_assignment() { + for (int i = 0; i < 9; i++) { +i = i + 1; +clang_analyzer_numTimesReached(); // expected-warning {{4}} + } + return 0; +} + +int no_unroll_assignment2() { + for (int i = 0; i < 9; i++) { +i *= 2; +clang_analyzer_numTimesReached(); // expected-warning {{4}} + } + return 0; +} + +int no_unroll_assignment3() { + for (int i = 128; i > 0; i--) { +i /= 2; +clang_analyzer_numTimesReached(); // expected-warning {{4}} + } + return 0; +} + +int no_unroll_assignment4() { + for (int i = 0; i < 9; i++) { +i -= 2; +clang_analyzer_numTimesReached(); // expected-warning {{4}} + } + return 0; +} + +int no_unroll_assignment5() { + for (int i = 0; i < 9; i++) { +i += 1; +clang_analyzer_numTimesReached(); // expected-warning {{4}} + } + return 0; +} + +int no_unroll_assignment6() { + for (int i = 128; i > 0; i--) { +i >>= 1; +clang_analyzer_numTimesReached(); // expected-warning {{4}} + } + return 0; +} + +int no_unroll_assignment7() { + for (int i = 0; i < 512; i++) { +i <<= 1; +clang_analyzer_numTimesReached(); // expected-warning {{4}} + } + return 0; +} + +int no_unroll_assignment8() { + for (int i = 0; i < 9; i++) { +i %= 8; +clang_analyzer_numTimesReached(); // expected-warning {{4}} + } + return 0; +} + +int no_unroll_assignment9() { + for (int i = 0; i < 9; i++) { +i &= 31; +clang_analyzer_numTimesReached(); // expected-warning {{4}} + } + return 0; +} + +int no_unroll_assignment10() { + for (int i = 0; i < 9; i++) { +i |= 2; +clang_analyzer_numTimesReached(); // expected-warning {{4}} + } + return 0; +} + +int no_unroll_assignment11() { + for (int i = 0; i < 9; i++) { +i ^= 2; +clang_analyzer_numTimesReached(); // expected-warning {{4}} + } + return 0; +} + int make_new_branches_loop_cached() { for (int i = 0; i < 8; i++) { clang_analyzer_numTimesReached(); // expected-warning {{4}} -if(getNum()){ -(void) i; // Since this Stmt does not change the State the analyzer - // won't make a new execution path but reuse the earlier nodes. - } +if (getNum()) { + (void)i; // Since this Stmt does not change the State the analyzer + // won't make a new execution path but reuse the earlier nodes. +} } clang_analyzer_warnIfReached(); // no-warning return 0; @@ -114,7 +202,7 @@ int l = 2; for (int i = 0; i < 8; i++) { clang_analyzer_numTimesReached(); // expected-warning {{10}} -if(getNum()){ +if (getNum()) { ++l; } } @@ -126,7 +214,7 @@ int l = 2; for (int i = 0; i < 8; i++) { clang_analyzer_numTimesReached(); // expected-warning {{10}} -if(getNum()){ +if (getNum()) { ++l; } (void)&i; // This ensures that the loop won't be unrolled. @@ -184,7 +272,7 @@ for (j = 0; j < 9; ++j) { clang_analyzer_numTimesReached(); // expected-warning {{4}} a[j] = 22; - (void) &j; // ensures that the inner loop won't be unrolled + (void)&j; // ensures that the inner loop won't be unrolled } a[i] = 42; } @@ -263,8 +351,8 @@ int k = 2; for (int i = 0; i < 5; i++) { clang_analyzer_numTimesReached(); // expected-warning {{13}} -if(i == 0 && b) // Splits the state in the first iteration but the recursion -// call will be unrolled anyway since the condition is known there. +if (i == 0 && b) // Splits the state in the first iteration but the recursion + // call will be unrolled anyway since the condition is known there. recursion_unroll1(false); clang_analyzer_numTimesReached(); // expected-warning {{14}} } @@ -276,7 +364,7 @@ int k = 0; for (int i = 0; i < 5; i++) { clang_analyzer_numTimesReached(); // expected-warning {{9}} -if(i == 0 && b) +if (i == 0 && b) recursion_unroll2(false); clang_analyzer_numTimesReached(); // expected-warning {{9}} } @@ -302,7 +390,7 @@ int k = 2; for (int i = 0; i < 5; i++) { clang_analyzer_numTimesReached(); // expected-warning {{13}} -if(i == 0 && b) { +if (i == 0 && b) { recursion_unroll4(false); continue; } Index: lib/StaticAnalyzer/Core/LoopUnrolling.cpp === --- lib/StaticAnalyzer/Core/LoopUnrolling.cpp +++ lib/StaticAnalyzer/Core/LoopUnrollin
r316830 - [analyzer] LoopUnrolling: check the bitwidth of the used numbers (pr34943)
Author: szepet Date: Sat Oct 28 05:19:08 2017 New Revision: 316830 URL: http://llvm.org/viewvc/llvm-project?rev=316830&view=rev Log: [analyzer] LoopUnrolling: check the bitwidth of the used numbers (pr34943) The loop unrolling feature aims to track the maximum possible steps a loop can make. In order to implement this, it investigates the initial value of the counter variable and the bound number. (It has to be known.) These numbers are used as llvm::APInts, however, it was not checked if their bitwidths are the same which lead to some crashes. This revision solves this problem by extending the "shorter" one (to the length of the "longer" one). For the detailed bug report, see: https://bugs.llvm.org/show_bug.cgi?id=34943 Differential Revision: https://reviews.llvm.org/D38922 Modified: cfe/trunk/lib/StaticAnalyzer/Core/LoopUnrolling.cpp cfe/trunk/test/Analysis/loop-unrolling.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Core/LoopUnrolling.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/LoopUnrolling.cpp?rev=316830&r1=316829&r2=316830&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Core/LoopUnrolling.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/LoopUnrolling.cpp Sat Oct 28 05:19:08 2017 @@ -208,9 +208,16 @@ bool shouldCompletelyUnroll(const Stmt * return false; auto CounterVar = Matches[0].getNodeAs("initVarName"); - auto BoundNum = Matches[0].getNodeAs("boundNum")->getValue(); - auto InitNum = Matches[0].getNodeAs("initNum")->getValue(); + llvm::APInt BoundNum = + Matches[0].getNodeAs("boundNum")->getValue(); + llvm::APInt InitNum = + Matches[0].getNodeAs("initNum")->getValue(); auto CondOp = Matches[0].getNodeAs("conditionOperator"); + if (InitNum.getBitWidth() != BoundNum.getBitWidth()) { +InitNum = InitNum.zextOrSelf(BoundNum.getBitWidth()); +BoundNum = BoundNum.zextOrSelf(InitNum.getBitWidth()); + } + if (CondOp->getOpcode() == BO_GE || CondOp->getOpcode() == BO_LE) maxStep = (BoundNum - InitNum + 1).abs().getZExtValue(); else Modified: cfe/trunk/test/Analysis/loop-unrolling.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/loop-unrolling.cpp?rev=316830&r1=316829&r2=316830&view=diff == --- cfe/trunk/test/Analysis/loop-unrolling.cpp (original) +++ cfe/trunk/test/Analysis/loop-unrolling.cpp Sat Oct 28 05:19:08 2017 @@ -373,3 +373,9 @@ int num_steps_over_limit3() { return 0; } + +void pr34943() { + for (int i = 0; i < 6L; ++i) { +clang_analyzer_numTimesReached(); // expected-warning {{6}} + } +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38922: [analyzer] LoopUnrolling: check the bitwidth of the used numbers (pr34943)
This revision was automatically updated to reflect the committed changes. Closed by commit rL316830: [analyzer] LoopUnrolling: check the bitwidth of the used numbers (pr34943) (authored by szepet). Changed prior to commit: https://reviews.llvm.org/D38922?vs=119019&id=120733#toc Repository: rL LLVM https://reviews.llvm.org/D38922 Files: cfe/trunk/lib/StaticAnalyzer/Core/LoopUnrolling.cpp cfe/trunk/test/Analysis/loop-unrolling.cpp Index: cfe/trunk/lib/StaticAnalyzer/Core/LoopUnrolling.cpp === --- cfe/trunk/lib/StaticAnalyzer/Core/LoopUnrolling.cpp +++ cfe/trunk/lib/StaticAnalyzer/Core/LoopUnrolling.cpp @@ -208,9 +208,16 @@ return false; auto CounterVar = Matches[0].getNodeAs("initVarName"); - auto BoundNum = Matches[0].getNodeAs("boundNum")->getValue(); - auto InitNum = Matches[0].getNodeAs("initNum")->getValue(); + llvm::APInt BoundNum = + Matches[0].getNodeAs("boundNum")->getValue(); + llvm::APInt InitNum = + Matches[0].getNodeAs("initNum")->getValue(); auto CondOp = Matches[0].getNodeAs("conditionOperator"); + if (InitNum.getBitWidth() != BoundNum.getBitWidth()) { +InitNum = InitNum.zextOrSelf(BoundNum.getBitWidth()); +BoundNum = BoundNum.zextOrSelf(InitNum.getBitWidth()); + } + if (CondOp->getOpcode() == BO_GE || CondOp->getOpcode() == BO_LE) maxStep = (BoundNum - InitNum + 1).abs().getZExtValue(); else Index: cfe/trunk/test/Analysis/loop-unrolling.cpp === --- cfe/trunk/test/Analysis/loop-unrolling.cpp +++ cfe/trunk/test/Analysis/loop-unrolling.cpp @@ -373,3 +373,9 @@ return 0; } + +void pr34943() { + for (int i = 0; i < 6L; ++i) { +clang_analyzer_numTimesReached(); // expected-warning {{6}} + } +} Index: cfe/trunk/lib/StaticAnalyzer/Core/LoopUnrolling.cpp === --- cfe/trunk/lib/StaticAnalyzer/Core/LoopUnrolling.cpp +++ cfe/trunk/lib/StaticAnalyzer/Core/LoopUnrolling.cpp @@ -208,9 +208,16 @@ return false; auto CounterVar = Matches[0].getNodeAs("initVarName"); - auto BoundNum = Matches[0].getNodeAs("boundNum")->getValue(); - auto InitNum = Matches[0].getNodeAs("initNum")->getValue(); + llvm::APInt BoundNum = + Matches[0].getNodeAs("boundNum")->getValue(); + llvm::APInt InitNum = + Matches[0].getNodeAs("initNum")->getValue(); auto CondOp = Matches[0].getNodeAs("conditionOperator"); + if (InitNum.getBitWidth() != BoundNum.getBitWidth()) { +InitNum = InitNum.zextOrSelf(BoundNum.getBitWidth()); +BoundNum = BoundNum.zextOrSelf(InitNum.getBitWidth()); + } + if (CondOp->getOpcode() == BO_GE || CondOp->getOpcode() == BO_LE) maxStep = (BoundNum - InitNum + 1).abs().getZExtValue(); else Index: cfe/trunk/test/Analysis/loop-unrolling.cpp === --- cfe/trunk/test/Analysis/loop-unrolling.cpp +++ cfe/trunk/test/Analysis/loop-unrolling.cpp @@ -373,3 +373,9 @@ return 0; } + +void pr34943() { + for (int i = 0; i < 6L; ++i) { +clang_analyzer_numTimesReached(); // expected-warning {{6}} + } +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r316832 - [clangd] Fix clang-tidy warnings.
Author: d0k Date: Sat Oct 28 10:32:56 2017 New Revision: 316832 URL: http://llvm.org/viewvc/llvm-project?rev=316832&view=rev Log: [clangd] Fix clang-tidy warnings. No functionality change intended. Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.h clang-tools-extra/trunk/clangd/ClangdServer.cpp clang-tools-extra/trunk/clangd/ClangdUnit.cpp clang-tools-extra/trunk/clangd/ClangdUnit.h clang-tools-extra/trunk/clangd/ClangdUnitStore.cpp clang-tools-extra/trunk/clangd/ClangdUnitStore.h clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdLSPServer.h?rev=316832&r1=316831&r2=316832&view=diff == --- clang-tools-extra/trunk/clangd/ClangdLSPServer.h (original) +++ clang-tools-extra/trunk/clangd/ClangdLSPServer.h Sat Oct 28 10:32:56 2017 @@ -73,12 +73,6 @@ private: std::vector getFixIts(StringRef File, const clangd::Diagnostic &D); - /// Function that will be called on a separate thread when diagnostics are - /// ready. Sends the Dianostics to LSP client via Out.writeMessage and caches - /// corresponding fixits in the FixItsMap. - void consumeDiagnostics(PathRef File, - std::vector Diagnostics); - JSONOutput &Out; /// Used to indicate that the 'shutdown' request was received from the /// Language Server client. Modified: clang-tools-extra/trunk/clangd/ClangdServer.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.cpp?rev=316832&r1=316831&r2=316832&view=diff == --- clang-tools-extra/trunk/clangd/ClangdServer.cpp (original) +++ clang-tools-extra/trunk/clangd/ClangdServer.cpp Sat Oct 28 10:32:56 2017 @@ -166,8 +166,8 @@ std::future ClangdServer::addDocum DocVersion Version = DraftMgr.updateDraft(File, Contents); auto TaggedFS = FSProvider.getTaggedFileSystem(File); - std::shared_ptr Resources = Units.getOrCreateFile( - File, ResourceDir, CDB, PCHs, TaggedFS.Value, Logger); + std::shared_ptr Resources = + Units.getOrCreateFile(File, ResourceDir, CDB, PCHs, Logger); return scheduleReparseAndDiags(File, VersionedDraft{Version, Contents.str()}, std::move(Resources), std::move(TaggedFS)); } @@ -184,8 +184,8 @@ std::future ClangdServer::forceRep "forceReparse() was called for non-added document"); auto TaggedFS = FSProvider.getTaggedFileSystem(File); - auto Recreated = Units.recreateFileIfCompileCommandChanged( - File, ResourceDir, CDB, PCHs, TaggedFS.Value, Logger); + auto Recreated = Units.recreateFileIfCompileCommandChanged(File, ResourceDir, + CDB, PCHs, Logger); // Note that std::future from this cleanup action is ignored. scheduleCancelRebuild(std::move(Recreated.RemovedFile)); Modified: clang-tools-extra/trunk/clangd/ClangdUnit.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdUnit.cpp?rev=316832&r1=316831&r2=316832&view=diff == --- clang-tools-extra/trunk/clangd/ClangdUnit.cpp (original) +++ clang-tools-extra/trunk/clangd/ClangdUnit.cpp Sat Oct 28 10:32:56 2017 @@ -157,7 +157,7 @@ getOptionalParameters(const CodeCompleti return Result; } -llvm::Optional toClangdDiag(StoredDiagnostic D) { +llvm::Optional toClangdDiag(const StoredDiagnostic &D) { auto Location = D.getLocation(); if (!Location.isValid() || !Location.getManager().isInMainFile(Location)) return llvm::None; @@ -744,9 +744,9 @@ bool invokeCodeComplete(std::unique_ptr< Preamble = nullptr; } - auto Clang = prepareCompilerInstance(std::move(CI), Preamble, - std::move(ContentsBuffer), PCHs, VFS, - DummyDiagsConsumer); + auto Clang = prepareCompilerInstance( + std::move(CI), Preamble, std::move(ContentsBuffer), std::move(PCHs), + std::move(VFS), DummyDiagsConsumer); auto &DiagOpts = Clang->getDiagnosticOpts(); DiagOpts.IgnoreWarnings = true; @@ -804,7 +804,7 @@ clang::CodeCompleteOptions clangd::CodeC } std::vector -clangd::codeComplete(PathRef FileName, tooling::CompileCommand Command, +clangd::codeComplete(PathRef FileName, const tooling::CompileCommand &Command, PrecompiledPreamble const *Preamble, StringRef Contents, Position Pos, IntrusiveRefCntPtr VFS, std::shared_ptr PCHs, @@ -826,7 +826,7 @@ clangd::codeComplete(PathRef FileName, t } SignatureHelp -clangd::signatureHelp(PathRef FileName, tooling::CompileCommand Command, +clangd::signatureHelp(PathRef FileName, const tooling::CompileCommand &Comman
r316836 - PR35039: Materialize temporary objects before wrapping them in an
Author: rsmith Date: Sat Oct 28 11:59:51 2017 New Revision: 316836 URL: http://llvm.org/viewvc/llvm-project?rev=316836&view=rev Log: PR35039: Materialize temporary objects before wrapping them in an OpaqueValueExpr in a GNU binary conditional expression. It's not meaningful for a non-materialized temporary object to be used as a common subexpression of multiple expressions. Modified: cfe/trunk/lib/Sema/SemaExpr.cpp cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp cfe/trunk/test/CodeGenCXX/cxx1z-copy-omission.cpp Modified: cfe/trunk/lib/Sema/SemaExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=316836&r1=316835&r2=316836&view=diff == --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) +++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Oct 28 11:59:51 2017 @@ -7242,6 +7242,16 @@ ExprResult Sema::ActOnConditionalOp(Sour commonExpr = commonRes.get(); } +// If the common expression is a class or array prvalue, materialize it +// so that we can safely refer to it multiple times. +if (commonExpr->isRValue() && (commonExpr->getType()->isRecordType() || + commonExpr->getType()->isArrayType())) { + ExprResult MatExpr = TemporaryMaterializationConversion(commonExpr); + if (MatExpr.isInvalid()) +return ExprError(); + commonExpr = MatExpr.get(); +} + opaqueValue = new (Context) OpaqueValueExpr(commonExpr->getExprLoc(), commonExpr->getType(), commonExpr->getValueKind(), Modified: cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp?rev=316836&r1=316835&r2=316836&view=diff == --- cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp (original) +++ cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp Sat Oct 28 11:59:51 2017 @@ -834,7 +834,8 @@ int testConsistencyNestedNormalReturn(bo // CHECK: Preds (1): B4 // CHECK: Succs (1): B1 // CHECK: [B4] -// CHECK: 1: [B7.2] ?: [B6.6] +// CXX98: 1: [B7.2] ?: [B6.6] +// CXX11: 1: [B7.3] ?: [B6.6] // CHECK: 2: [B4.1] (ImplicitCastExpr, NoOp, const class A) // CHECK: 3: [B4.2] // CHECK: 4: [B4.3] (CXXConstructExpr, class A) @@ -843,10 +844,13 @@ int testConsistencyNestedNormalReturn(bo // CHECK: Preds (2): B5 B6 // CHECK: Succs (2): B3 B2 // CHECK: [B5] -// CHECK: 1: [B7.2] (ImplicitCastExpr, NoOp, const class A) -// CHECK: 2: [B5.1] -// CHECK: 3: [B5.2] (CXXConstructExpr, class A) -// CHECK: 4: [B5.3] (BindTemporary) +// CXX98: 1: [B7.2] (ImplicitCastExpr, NoOp, const class A) +// CXX98: 2: [B5.1] +// CXX98: 3: [B5.2] (CXXConstructExpr, class A) +// CXX98: 4: [B5.3] (BindTemporary) +// CXX11: 1: [B7.3] (ImplicitCastExpr, NoOp, const class A) +// CXX11: 2: [B5.1] (CXXConstructExpr, class A) +// CXX11: 3: [B5.2] (BindTemporary) // CHECK: Preds (1): B7 // CHECK: Succs (1): B4 // CHECK: [B6] @@ -861,10 +865,15 @@ int testConsistencyNestedNormalReturn(bo // CHECK: [B7] // CHECK: 1: A() (CXXConstructExpr, class A) // CHECK: 2: [B7.1] (BindTemporary) -// CHECK: 3: [B7.2].operator bool -// CHECK: 4: [B7.2] -// CHECK: 5: [B7.4] (ImplicitCastExpr, UserDefinedConversion, _Bool) -// CHECK: T: [B7.5] ? ... : ... +// CXX98: 3: [B7.2].operator bool +// CXX98: 4: [B7.2] +// CXX98: 5: [B7.4] (ImplicitCastExpr, UserDefinedConversion, _Bool) +// CXX98: T: [B7.5] ? ... : ... +// CXX11: 3: [B7.2] +// CXX11: 4: [B7.3].operator bool +// CXX11: 5: [B7.3] +// CXX11: 6: [B7.5] (ImplicitCastExpr, UserDefinedConversion, _Bool) +// CXX11: T: [B7.6] ? ... : ... // CHECK: Preds (1): B8 // CHECK: Succs (2): B5 B6 // CHECK: [B0 (EXIT)] @@ -886,7 +895,8 @@ int testConsistencyNestedNormalReturn(bo // CHECK: Preds (1): B4 // CHECK: Succs (1): B1 // CHECK: [B4] -// CHECK: 1: [B7.4] ?: [B6.6] +// CXX98: 1: [B7.4] ?: [B6.6] +// CXX11: 1: [B7.5] ?: [B6.6] // CHECK: 2: [B4.1] (ImplicitCastExpr, NoOp, const class A) // CHECK: 3: [B4.2] // CHECK: 4: [B7.2]([B4.3]) @@ -894,10 +904,13 @@ int testConsistencyNestedNormalReturn(bo // CHECK: Preds (2): B5 B6 // CHECK: Succs (2): B3 B2 // CHECK: [B5] -// CHECK: 1: [B7.4] (ImplicitCastExpr, NoOp, const class A) -// CHECK: 2: [B5.1] -// CHECK: 3: [B5.2] (CXXConstructExpr, class A) -// CHECK: 4: [B5.3] (BindTemporary) +// CXX98: 1: [B7.4] (ImplicitCastExpr, NoOp, const class A) +// CXX98: 2: [B5.1] +// CXX98: 3: [B5.2] (CXXConstructExpr, class A) +// CXX98: 4: [B5.3] (BindTemporary) +// CXX11: 1: [B7.5] (ImplicitCastExpr, NoOp, const cla
[libunwind] r316843 - Restore arch specific lastDwarfRegNum in builds without _LIBUNWIND_IS_NATIVE_ONLY
Author: mstorsjo Date: Sat Oct 28 13:19:49 2017 New Revision: 316843 URL: http://llvm.org/viewvc/llvm-project?rev=316843&view=rev Log: Restore arch specific lastDwarfRegNum in builds without _LIBUNWIND_IS_NATIVE_ONLY This restores the previous behaviour of the Registers_* classes after SVN r316745. Differential Revision: https://reviews.llvm.org/D39382 Modified: libunwind/trunk/include/__libunwind_config.h libunwind/trunk/src/Registers.hpp Modified: libunwind/trunk/include/__libunwind_config.h URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/include/__libunwind_config.h?rev=316843&r1=316842&r2=316843&view=diff == --- libunwind/trunk/include/__libunwind_config.h (original) +++ libunwind/trunk/include/__libunwind_config.h Sat Oct 28 13:19:49 2017 @@ -15,33 +15,39 @@ #define _LIBUNWIND_ARM_EHABI #endif +#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86 8 +#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_6432 +#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC 112 +#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64 95 +#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM 95 +#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K 31 + #if defined(_LIBUNWIND_IS_NATIVE_ONLY) # if defined(__i386__) # define _LIBUNWIND_TARGET_I386 # define _LIBUNWIND_CONTEXT_SIZE 8 # define _LIBUNWIND_CURSOR_SIZE 19 -# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 8 +# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86 # elif defined(__x86_64__) # define _LIBUNWIND_TARGET_X86_64 1 # if defined(_WIN64) #define _LIBUNWIND_CONTEXT_SIZE 54 #define _LIBUNWIND_CURSOR_SIZE 66 -#define _LIBUNWIND_HIGHEST_DWARF_REGISTER 32 # else #define _LIBUNWIND_CONTEXT_SIZE 21 #define _LIBUNWIND_CURSOR_SIZE 33 -#define _LIBUNWIND_HIGHEST_DWARF_REGISTER 16 # endif +# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64 # elif defined(__ppc__) # define _LIBUNWIND_TARGET_PPC 1 # define _LIBUNWIND_CONTEXT_SIZE 117 # define _LIBUNWIND_CURSOR_SIZE 128 -# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 112 +# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC # elif defined(__aarch64__) # define _LIBUNWIND_TARGET_AARCH64 1 # define _LIBUNWIND_CONTEXT_SIZE 66 # define _LIBUNWIND_CURSOR_SIZE 78 -# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 95 +# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64 # elif defined(__arm__) # define _LIBUNWIND_TARGET_ARM 1 # if defined(__ARM_WMMX) @@ -51,12 +57,12 @@ #define _LIBUNWIND_CONTEXT_SIZE 42 #define _LIBUNWIND_CURSOR_SIZE 49 # endif -# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 95 +# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM # elif defined(__or1k__) # define _LIBUNWIND_TARGET_OR1K 1 # define _LIBUNWIND_CONTEXT_SIZE 16 # define _LIBUNWIND_CURSOR_SIZE 28 -# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 31 +# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K # else # error "Unsupported architecture." # endif Modified: libunwind/trunk/src/Registers.hpp URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/Registers.hpp?rev=316843&r1=316842&r2=316843&view=diff == --- libunwind/trunk/src/Registers.hpp (original) +++ libunwind/trunk/src/Registers.hpp Sat Oct 28 13:19:49 2017 @@ -44,7 +44,7 @@ public: voidsetVectorRegister(int num, v128 value); const char *getRegisterName(int num); voidjumpto(); - static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER; } + static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86; } uint32_t getSP() const { return _registers.__esp; } void setSP(uint32_t value) { _registers.__esp = value; } @@ -250,7 +250,7 @@ public: voidsetVectorRegister(int num, v128 value); const char *getRegisterName(int num); voidjumpto(); - static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER; } + static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64; } uint64_t getSP() const { return _registers.__rsp; } void setSP(uint64_t value) { _registers.__rsp = value; } @@ -560,7 +560,7 @@ public: voidsetVectorRegister(int num, v128 value); const char *getRegisterName(int num); voidjumpto(); - static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER; } + static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC; } uint64_t getSP() const { return _registers.__r1; } void setSP(uint32_t value) { _registers.__r1 = value; } @@ -1126,7 +1126,7 @@ public: voidsetVectorRegister(int num, v128 value); const char *getReg
[PATCH] D39382: [libunwind] Restore arch specific lastDwarfRegNum in builds without _LIBUNWIND_IS_NATIVE_ONLY
This revision was automatically updated to reflect the committed changes. Closed by commit rL316843: Restore arch specific lastDwarfRegNum in builds without… (authored by mstorsjo). Changed prior to commit: https://reviews.llvm.org/D39382?vs=120679&id=120736#toc Repository: rL LLVM https://reviews.llvm.org/D39382 Files: libunwind/trunk/include/__libunwind_config.h libunwind/trunk/src/Registers.hpp Index: libunwind/trunk/src/Registers.hpp === --- libunwind/trunk/src/Registers.hpp +++ libunwind/trunk/src/Registers.hpp @@ -44,7 +44,7 @@ voidsetVectorRegister(int num, v128 value); const char *getRegisterName(int num); voidjumpto(); - static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER; } + static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86; } uint32_t getSP() const { return _registers.__esp; } void setSP(uint32_t value) { _registers.__esp = value; } @@ -250,7 +250,7 @@ voidsetVectorRegister(int num, v128 value); const char *getRegisterName(int num); voidjumpto(); - static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER; } + static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64; } uint64_t getSP() const { return _registers.__rsp; } void setSP(uint64_t value) { _registers.__rsp = value; } @@ -560,7 +560,7 @@ voidsetVectorRegister(int num, v128 value); const char *getRegisterName(int num); voidjumpto(); - static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER; } + static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC; } uint64_t getSP() const { return _registers.__r1; } void setSP(uint32_t value) { _registers.__r1 = value; } @@ -1126,7 +1126,7 @@ voidsetVectorRegister(int num, v128 value); const char *getRegisterName(int num); voidjumpto(); - static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER; } + static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64; } uint64_t getSP() const { return _registers.__sp; } void setSP(uint64_t value) { _registers.__sp = value; } @@ -1875,7 +1875,7 @@ voidsetVectorRegister(int num, v128 value); const char *getRegisterName(int num); voidjumpto(); - static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER; } + static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K; } uint64_t getSP() const { return _registers.__r[1]; } void setSP(uint32_t value) { _registers.__r[1] = value; } Index: libunwind/trunk/include/__libunwind_config.h === --- libunwind/trunk/include/__libunwind_config.h +++ libunwind/trunk/include/__libunwind_config.h @@ -15,33 +15,39 @@ #define _LIBUNWIND_ARM_EHABI #endif +#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86 8 +#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_6432 +#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC 112 +#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64 95 +#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM 95 +#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K 31 + #if defined(_LIBUNWIND_IS_NATIVE_ONLY) # if defined(__i386__) # define _LIBUNWIND_TARGET_I386 # define _LIBUNWIND_CONTEXT_SIZE 8 # define _LIBUNWIND_CURSOR_SIZE 19 -# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 8 +# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86 # elif defined(__x86_64__) # define _LIBUNWIND_TARGET_X86_64 1 # if defined(_WIN64) #define _LIBUNWIND_CONTEXT_SIZE 54 #define _LIBUNWIND_CURSOR_SIZE 66 -#define _LIBUNWIND_HIGHEST_DWARF_REGISTER 32 # else #define _LIBUNWIND_CONTEXT_SIZE 21 #define _LIBUNWIND_CURSOR_SIZE 33 -#define _LIBUNWIND_HIGHEST_DWARF_REGISTER 16 # endif +# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64 # elif defined(__ppc__) # define _LIBUNWIND_TARGET_PPC 1 # define _LIBUNWIND_CONTEXT_SIZE 117 # define _LIBUNWIND_CURSOR_SIZE 128 -# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 112 +# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC # elif defined(__aarch64__) # define _LIBUNWIND_TARGET_AARCH64 1 # define _LIBUNWIND_CONTEXT_SIZE 66 # define _LIBUNWIND_CURSOR_SIZE 78 -# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 95 +# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64 # elif defined(__arm__) # define _LIBUNWIND_TARGET_ARM 1 # if defined(__ARM_WMMX) @@ -51,12 +57,12 @@ #define _LIBUNWIND_CONTEXT_SIZE 42 #define _LIBUNWIND_CURSOR_SIZE 49 # endif -# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 95 +# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGH
r316850 - [analyzer] MisusedMovedObjectChecker: Fix false positive on state-resetting, handling method calls on base-class sub-objects
Author: szepet Date: Sat Oct 28 16:09:37 2017 New Revision: 316850 URL: http://llvm.org/viewvc/llvm-project?rev=316850&view=rev Log: [analyzer] MisusedMovedObjectChecker: Fix false positive on state-resetting, handling method calls on base-class sub-objects An earlier solution from Artem r315301 solves the reset problem, however, the reports should be handled the same way in case of method calls. We should not just report the base class of the object where the method was defined but the whole object. Fixed false positive which came from not removing the subobjects in case of a state-resetting function. (Just replaced the State->remove(...) call to removeFromState(..) which was defined exactly for that purpose.) Some minor typos fixed in this patch as well which did not worth a whole new patch in my opinion, so included them here. Differential Revision: https://reviews.llvm.org/D31538 Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp cfe/trunk/test/Analysis/MisusedMovedObject.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp?rev=316850&r1=316849&r2=316850&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp Sat Oct 28 16:09:37 2017 @@ -352,7 +352,7 @@ void MisusedMovedObjectChecker::checkPre const LocationContext *LC = C.getLocationContext(); ExplodedNode *N = nullptr; - // Remove the MemRegions from the map on which a ctor/dtor call or assignement + // Remove the MemRegions from the map on which a ctor/dtor call or assignment // happened. // Checking constructor calls. @@ -380,8 +380,11 @@ void MisusedMovedObjectChecker::checkPre return; // In case of destructor call we do not track the object anymore. const MemRegion *ThisRegion = IC->getCXXThisVal().getAsRegion(); + if (!ThisRegion) +return; + if (dyn_cast_or_null(Call.getDecl())) { -State = removeFromState(State, IC->getCXXThisVal().getAsRegion()); +State = removeFromState(State, ThisRegion); C.addTransition(State); return; } @@ -412,28 +415,28 @@ void MisusedMovedObjectChecker::checkPre } // The remaining part is check only for method call on a moved-from object. + + // We want to investigate the whole object, not only sub-object of a parent + // class in which the encountered method defined. + while (const CXXBaseObjectRegion *BR = + dyn_cast(ThisRegion)) +ThisRegion = BR->getSuperRegion(); + if (isMoveSafeMethod(MethodDecl)) return; if (isStateResetMethod(MethodDecl)) { -// A state reset method resets the whole object, not only sub-object -// of a parent class in which it is defined. -const MemRegion *WholeObjectRegion = ThisRegion; -while (const CXXBaseObjectRegion *BR = - dyn_cast(WholeObjectRegion)) - WholeObjectRegion = BR->getSuperRegion(); - -State = State->remove(WholeObjectRegion); +State = removeFromState(State, ThisRegion); C.addTransition(State); return; } - // If it is already reported then we dont report the bug again. + // If it is already reported then we don't report the bug again. const RegionState *ThisState = State->get(ThisRegion); if (!(ThisState && ThisState->isMoved())) return; - // Dont report it in case if any base region is already reported + // Don't report it in case if any base region is already reported if (isAnyBaseRegionReported(State, ThisRegion)) return; Modified: cfe/trunk/test/Analysis/MisusedMovedObject.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/MisusedMovedObject.cpp?rev=316850&r1=316849&r2=316850&view=diff == --- cfe/trunk/test/Analysis/MisusedMovedObject.cpp (original) +++ cfe/trunk/test/Analysis/MisusedMovedObject.cpp Sat Oct 28 16:09:37 2017 @@ -332,6 +332,8 @@ void moveStateResetFunctionsTest() { A b = std::move(a); a.reset(); // no-warning a.foo(); // no-warning +// Test if resets the state of subregions as well. +a.b.foo(); // no-warning } { A a; @@ -344,6 +346,7 @@ void moveStateResetFunctionsTest() { A b = std::move(a); a.clear(); // no-warning a.foo(); // no-warning +a.b.foo(); // no-warning } } @@ -444,7 +447,7 @@ void differentBranchesTest(int i) { // Same thing, but with a switch statement. { A a, b; -switch (i) { // expected-note {{Control jumps to 'case 1:' at line 448}} +switch (i) { // expected-note {{Control jumps to 'case 1:' at line 451}} case 1: b = std::move(a); // no-warning break;// expected-note {{Execution jumps to the
r316852 - [analyzer] MisusedMovedObjectChecker: More precise warning message
Author: szepet Date: Sat Oct 28 16:24:00 2017 New Revision: 316852 URL: http://llvm.org/viewvc/llvm-project?rev=316852&view=rev Log: [analyzer] MisusedMovedObjectChecker: More precise warning message Added new enum in order to differentiate the warning messages on "misusing" into 3 categories: function calls, moving an object, copying an object. (At the moment the checker gives the same message in case of copying and moving.) Additional test cases added as well. Differential Revision: https://reviews.llvm.org/D38674 Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp cfe/trunk/test/Analysis/MisusedMovedObject.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp?rev=316852&r1=316851&r2=316852&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp Sat Oct 28 16:24:00 2017 @@ -60,6 +60,7 @@ public: const char *NL, const char *Sep) const override; private: + enum MisuseKind {MK_FunCall, MK_Copy, MK_Move}; class MovedBugVisitor : public BugReporterVisitorImpl { public: MovedBugVisitor(const MemRegion *R) : Region(R), Found(false) {} @@ -83,7 +84,7 @@ private: mutable std::unique_ptr BT; ExplodedNode *reportBug(const MemRegion *Region, const CallEvent &Call, - CheckerContext &C, bool isCopy) const; + CheckerContext &C, MisuseKind MK) const; bool isInMoveSafeContext(const LocationContext *LC) const; bool isStateResetMethod(const CXXMethodDecl *MethodDec) const; bool isMoveSafeMethod(const CXXMethodDecl *MethodDec) const; @@ -179,7 +180,7 @@ const ExplodedNode *MisusedMovedObjectCh ExplodedNode *MisusedMovedObjectChecker::reportBug(const MemRegion *Region, const CallEvent &Call, CheckerContext &C, - bool isCopy = false) const { + MisuseKind MK) const { if (ExplodedNode *N = C.generateNonFatalErrorNode()) { if (!BT) BT.reset(new BugType(this, "Usage of a 'moved-from' object", @@ -195,10 +196,17 @@ ExplodedNode *MisusedMovedObjectChecker: // Creating the error message. std::string ErrorMessage; -if (isCopy) - ErrorMessage = "Copying a 'moved-from' object"; -else - ErrorMessage = "Method call on a 'moved-from' object"; +switch(MK) { + case MK_FunCall: +ErrorMessage = "Method call on a 'moved-from' object"; +break; + case MK_Copy: +ErrorMessage = "Copying a 'moved-from' object"; +break; + case MK_Move: +ErrorMessage = "Moving a 'moved-from' object"; +break; +} if (const auto DecReg = Region->getAs()) { const auto *RegionDecl = dyn_cast(DecReg->getDecl()); ErrorMessage += " '" + RegionDecl->getNameAsString() + "'"; @@ -365,7 +373,10 @@ void MisusedMovedObjectChecker::checkPre const RegionState *ArgState = State->get(ArgRegion); if (ArgState && ArgState->isMoved()) { if (!isInMoveSafeContext(LC)) { - N = reportBug(ArgRegion, Call, C, /*isCopy=*/true); + if(CtorDec->isMoveConstructor()) +N = reportBug(ArgRegion, Call, C, MK_Move); + else +N = reportBug(ArgRegion, Call, C, MK_Copy); State = State->set(ArgRegion, RegionState::getReported()); } @@ -405,7 +416,10 @@ void MisusedMovedObjectChecker::checkPre State->get(IC->getArgSVal(0).getAsRegion()); if (ArgState && ArgState->isMoved() && !isInMoveSafeContext(LC)) { const MemRegion *ArgRegion = IC->getArgSVal(0).getAsRegion(); -N = reportBug(ArgRegion, Call, C, /*isCopy=*/true); +if(MethodDecl->isMoveAssignmentOperator()) + N = reportBug(ArgRegion, Call, C, MK_Move); +else + N = reportBug(ArgRegion, Call, C, MK_Copy); State = State->set(ArgRegion, RegionState::getReported()); } @@ -443,7 +457,7 @@ void MisusedMovedObjectChecker::checkPre if (isInMoveSafeContext(LC)) return; - N = reportBug(ThisRegion, Call, C); + N = reportBug(ThisRegion, Call, C, MK_FunCall); State = State->set(ThisRegion, RegionState::getReported()); C.addTransition(State, N); } Modified: cfe/trunk/test/Analysis/MisusedMovedObject.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/MisusedMovedObject.cpp?rev=316852&r1=316851&r2=316852&view=diff == --- cfe/trunk/
[PATCH] D38674: [analyzer] MisusedMovedObjectChecker: More precise warning message
This revision was automatically updated to reflect the committed changes. Closed by commit rL316852: [analyzer] MisusedMovedObjectChecker: More precise warning message (authored by szepet). Changed prior to commit: https://reviews.llvm.org/D38674?vs=118170&id=120737#toc Repository: rL LLVM https://reviews.llvm.org/D38674 Files: cfe/trunk/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp cfe/trunk/test/Analysis/MisusedMovedObject.cpp Index: cfe/trunk/test/Analysis/MisusedMovedObject.cpp === --- cfe/trunk/test/Analysis/MisusedMovedObject.cpp +++ cfe/trunk/test/Analysis/MisusedMovedObject.cpp @@ -38,6 +38,7 @@ B() = default; B(const B &) = default; B(B &&) = default; + B& operator=(const B &q) = default; void operator=(B &&b) { return; } @@ -70,6 +71,12 @@ A(A &&other, char *k) { moveconstruct(std::move(other)); } + void operator=(const A &other) { +i = other.i; +d = other.d; +b = other.b; +return; + } void operator=(A &&other) { moveconstruct(std::move(other)); return; @@ -105,17 +112,42 @@ } void simpleMoveCtorTest() { - A a; - A b; - b = std::move(a); // expected-note {{'a' became 'moved-from' here}} - a.foo(); // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}} + { +A a; +A b = std::move(a); // expected-note {{'a' became 'moved-from' here}} +a.foo();// expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}} + } + { +A a; +A b = std::move(a); // expected-note {{'a' became 'moved-from' here}} +b = a; // expected-warning {{Copying a 'moved-from' object 'a'}} expected-note {{Copying a 'moved-from' object 'a'}} + } + { +A a; +A b = std::move(a); // expected-note {{'a' became 'moved-from' here}} +b = std::move(a); // expected-warning {{Moving a 'moved-from' object 'a'}} expected-note {{Moving a 'moved-from' object 'a'}} + } } void simpleMoveAssignementTest() { - A a; - A b; - b = std::move(a); // expected-note {{'a' became 'moved-from' here}} - a.foo(); // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}} + { +A a; +A b; +b = std::move(a); // expected-note {{'a' became 'moved-from' here}} +a.foo(); // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}} + } + { +A a; +A b; +b = std::move(a); // expected-note {{'a' became 'moved-from' here}} +A c(a); // expected-warning {{Copying a 'moved-from' object 'a'}} expected-note {{Copying a 'moved-from' object 'a'}} + } + { +A a; +A b; +b = std::move(a); // expected-note {{'a' became 'moved-from' here}} +A c(std::move(a)); // expected-warning {{Moving a 'moved-from' object 'a'}} expected-note {{Moving a 'moved-from' object 'a'}} + } } void moveInInitListTest() { @@ -270,7 +302,7 @@ { A a; for (int i = 0; i < bignum(); i++) { // expected-note {{Loop condition is true. Entering loop body}} expected-note {{Loop condition is true. Entering loop body}} - constCopyOrMoveCall(std::move(a)); // expected-warning {{Copying a 'moved-from' object 'a'}} expected-note {{Copying a 'moved-from' object 'a'}} + constCopyOrMoveCall(std::move(a)); // expected-warning {{Moving a 'moved-from' object 'a'}} expected-note {{Moving a 'moved-from' object 'a'}} // expected-note@-1 {{'a' became 'moved-from' here}} } } @@ -447,7 +479,7 @@ // Same thing, but with a switch statement. { A a, b; -switch (i) { // expected-note {{Control jumps to 'case 1:' at line 451}} +switch (i) { // expected-note {{Control jumps to 'case 1:' at line 483}} case 1: b = std::move(a); // no-warning break;// expected-note {{Execution jumps to the end of the function}} @@ -459,7 +491,7 @@ // However, if there's a fallthrough, we do warn. { A a, b; -switch (i) { // expected-note {{Control jumps to 'case 1:' at line 463}} +switch (i) { // expected-note {{Control jumps to 'case 1:' at line 495}} case 1: b = std::move(a); // expected-note {{'a' became 'moved-from' here}} case 2: Index: cfe/trunk/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp === --- cfe/trunk/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp +++ cfe/trunk/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp @@ -60,6 +60,7 @@ const char *NL, const char *Sep) const override; private: + enum MisuseKind {MK_FunCall, MK_Copy, MK_Move}; class MovedBugVisitor : public BugReporterVisitorImpl { public: MovedBugVisitor(const MemR
r316858 - Driver: default to `unsigned int` `wchar_t` for ARM
Author: compnerd Date: Sat Oct 28 23:01:14 2017 New Revision: 316858 URL: http://llvm.org/viewvc/llvm-project?rev=316858&view=rev Log: Driver: default to `unsigned int` `wchar_t` for ARM AAPCS and AAPCS64 mandate that `wchar_t` with `-fno-short-wchar` is an `unsigned int` rather than a `signed int`. Ensure that the driver does not flip the signedness of `wchar_t` for those targets. Add additional tests to ensure that this does not regress. Added: cfe/trunk/test/Driver/arm-wchar_t-defaults.c Modified: cfe/trunk/lib/Driver/ToolChains/Clang.cpp Modified: cfe/trunk/lib/Driver/ToolChains/Clang.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/Clang.cpp?rev=316858&r1=316857&r2=316858&view=diff == --- cfe/trunk/lib/Driver/ToolChains/Clang.cpp (original) +++ cfe/trunk/lib/Driver/ToolChains/Clang.cpp Sat Oct 28 23:01:14 2017 @@ -2622,8 +2622,13 @@ static void RenderCharacterOptions(const CmdArgs.push_back("-fwchar-type=short"); CmdArgs.push_back("-fno-signed-wchar"); } else { + bool IsARM = T.isARM() || T.isThumb() || T.isAArch64(); CmdArgs.push_back("-fwchar-type=int"); - CmdArgs.push_back("-fsigned-wchar"); + if (IsARM && !(T.isOSWindows() || T.getOS() == llvm::Triple::NetBSD || + T.getOS() == llvm::Triple::OpenBSD)) +CmdArgs.push_back("-fno-signed-wchar"); + else +CmdArgs.push_back("-fsigned-wchar"); } } } Added: cfe/trunk/test/Driver/arm-wchar_t-defaults.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/arm-wchar_t-defaults.c?rev=316858&view=auto == --- cfe/trunk/test/Driver/arm-wchar_t-defaults.c (added) +++ cfe/trunk/test/Driver/arm-wchar_t-defaults.c Sat Oct 28 23:01:14 2017 @@ -0,0 +1,53 @@ +// RUN: %clang -### -target armv7-unknown-none-eabi -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-SHORT %s +// RUN: %clang -### -target armv7-unknown-none-eabi -fno-short-wchar -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-LONG-UNSIGNED %s +// RUN: %clang -### -target armv7-unknown-none-eabi -mthumb -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-SHORT %s +// RUN: %clang -### -target armv7-unknown-none-eabi -mthumb -fno-short-wchar -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-LONG-UNSIGNED %s +// RUN: %clang -### -target armv7eb-unknown-none-eabi -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-SHORT %s +// RUN: %clang -### -target armv7eb-unknown-none-eabi -fno-short-wchar -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-LONG-UNSIGNED %s +// RUN: %clang -### -target armv7eb-unknown-none-eabi -mthumb -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-SHORT %s +// RUN: %clang -### -target armv7eb-unknown-none-eabi -mthumb -fno-short-wchar -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-LONG-UNSIGNED %s +// RUN: %clang -### -target aarch64-unknown-none-eabi -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-SHORT %s +// RUN: %clang -### -target aarch64-unknown-none-eabi -fno-short-wchar -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-LONG-UNSIGNED %s +// RUN: %clang -### -target aarch64_be-unknown-none-eabi -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-SHORT %s +// RUN: %clang -### -target aarch64_be-unknown-none-eabi -fno-short-wchar -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-LONG-UNSIGNED %s + +// RUN: %clang -### -target armv7-unknown-netbsd -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-SHORT %s +// RUN: %clang -### -target armv7-unknown-netbsd -fno-short-wchar -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-LONG-SIGNED %s +// RUN: %clang -### -target armv7-unknown-netbsd -mthumb -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-SHORT %s +// RUN: %clang -### -target armv7-unknown-netbsd -mthumb -fno-short-wchar -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-LONG-SIGNED %s +// RUN: %clang -### -target armv7eb-unknown-netbsd -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-SHORT %s +// RUN: %clang -### -target armv7eb-unknown-netbsd -fno-short-wchar -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-LONG-SIGNED %s +// RUN: %clang -### -target armv7eb-unknown-netbsd -mthumb -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-SHORT %s +// RUN: %clang -### -target armv7eb-unknown-netbsd -mthumb -fno-short-wchar -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-LONG-SIGNED %s +// RUN: %clang -### -target aarch64-unknown-netbsd -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-SHORT %s +// RUN: %clang -### -target aarch64-unknown-netbsd -fno-short-wchar -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-LONG-SIGNED %s +// RUN: %clang -### -target aarch64_be-unknown-netbsd -c %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-SHORT %s +// RU