From: Aleksei Sidorin Date: Tue, 21 Nov 2017 11:27:47 +0000 (+0000) Subject: [Analyzer] Stable iteration on indirect goto LabelDecl's to avoid non-determinism... X-Git-Tag: llvmorg-6.0.0-rc1~2915 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=124f5de84134095ac4cfa88eecfec1cf39995516;p=platform%2Fupstream%2Fllvm.git [Analyzer] Stable iteration on indirect goto LabelDecl's to avoid non-determinism (attempt 2) CFG wass built in non-deterministic order due to the fact that indirect goto labels' declarations (LabelDecl's) are stored in the llvm::SmallSet container. LabelDecl's are pointers, whose order is not deterministic, and llvm::SmallSet sorts them by their non-deterministic addresses after "small" container is exceeded. This leads to non-deterministic processing of the elements of the container. The fix is to use llvm::SmallSetVector that was designed to have deterministic iteration order. Patch by Ilya Palachev! Differential Revision: https://reviews.llvm.org/D40073 llvm-svn: 318754 --- diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index 164d964..c74ab5b 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -420,7 +420,7 @@ class CFGBuilder { BackpatchBlocksTy BackpatchBlocks; // A list of labels whose address has been taken (for indirect gotos). - typedef llvm::SmallPtrSet LabelSetTy; + typedef llvm::SmallSetVector LabelSetTy; LabelSetTy AddressTakenLabels; bool badCFG; diff --git a/clang/test/Analysis/cfg-indirect-goto-determinism.cpp b/clang/test/Analysis/cfg-indirect-goto-determinism.cpp new file mode 100644 index 0000000..895535e --- /dev/null +++ b/clang/test/Analysis/cfg-indirect-goto-determinism.cpp @@ -0,0 +1,96 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG %s 2>&1 | FileCheck %s + +void *target; +int indirectBlockSuccessorDeterminism() { + (void)&&L1; + (void)&&L2; + (void)&&L3; + (void)&&L4; + (void)&&L5; + (void)&&L6; + (void)&&L7; + (void)&&L8; + (void)&&L9; + (void)&&L10; + (void)&&L11; + (void)&&L12; + (void)&&L13; + (void)&&L14; + (void)&&L15; + (void)&&L16; + (void)&&L17; + (void)&&L18; + (void)&&L19; + (void)&&L20; + (void)&&L21; + (void)&&L22; + (void)&&L23; + (void)&&L24; + (void)&&L25; + (void)&&L26; + (void)&&L27; + (void)&&L28; + (void)&&L29; + (void)&&L30; + (void)&&L31; + (void)&&L32; + (void)&&L33; + (void)&&L34; + (void)&&L35; + (void)&&L36; + (void)&&L37; + (void)&&L38; + (void)&&L39; + (void)&&L40; + + goto *target; + L1: + L2: + L3: + L4: + L5: + L6: + L7: + L8: + L9: + L10: + L11: + L12: + L13: + L14: + L15: + L16: + L17: + L18: + L19: + L20: + L21: + L22: + L23: + L24: + L25: + L26: + L27: + L28: + L29: + L30: + L31: + L32: + L33: + L34: + L35: + L36: + L37: + L38: + L39: + L40: + return 0; +} + +// CHECK-LABEL: [B41 (INDIRECT GOTO DISPATCH)] +// CHECK-NEXT: Preds (1): B42 +// CHECK-NEXT: Succs (40): B1 B2 B3 B4 B5 B6 B7 B8 +// CHECK-NEXT: B9 B10 B11 B12 B13 B14 B15 B16 B17 B18 +// CHECK-NEXT: B19 B20 B21 B22 B23 B24 B25 B26 B27 B28 +// CHECK-NEXT: B29 B30 B31 B32 B33 B34 B35 B36 B37 B38 +// CHECK-NEXT: B39 B40