30 changes: 15 additions & 15 deletions clang/test/CoverageMapping/mcdc-logical-scalar-ids.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,25 @@ bool func_scalar_and(bool a, bool b, bool c, bool d, bool e, bool f) {
return bar(res1, res2, res3, res4, res5);
}

// CHECK-LABEL: Decision,File 0, 5:17 -> 5:23 = M:0, C:2
// CHECK-LABEL: Decision,File 0, 5:17 -> 5:23 = M:3, C:2
// CHECK-NEXT: Branch,File 0, 5:17 -> 5:18 = #1, (#0 - #1) [1,2,0]
// CHECK: Branch,File 0, 5:22 -> 5:23 = #2, (#1 - #2) [2,0,0]
// CHECK-LABEL: Decision,File 0, 6:17 -> 6:28 = M:1, C:3
// CHECK-LABEL: Decision,File 0, 6:17 -> 6:28 = M:7, C:3
// CHECK-NEXT: Branch,File 0, 6:17 -> 6:18 = #5, (#0 - #5) [1,3,0]
// CHECK: Branch,File 0, 6:22 -> 6:23 = #6, (#5 - #6) [3,2,0]
// CHECK: Branch,File 0, 6:27 -> 6:28 = #4, (#3 - #4) [2,0,0]
// CHECK-LABEL: Decision,File 0, 7:17 -> 7:33 = M:2, C:4
// CHECK-LABEL: Decision,File 0, 7:17 -> 7:33 = M:12, C:4
// CHECK-NEXT: Branch,File 0, 7:17 -> 7:18 = #11, (#0 - #11) [1,4,0]
// CHECK: Branch,File 0, 7:22 -> 7:23 = #12, (#11 - #12) [4,3,0]
// CHECK: Branch,File 0, 7:27 -> 7:28 = #10, (#9 - #10) [3,2,0]
// CHECK: Branch,File 0, 7:32 -> 7:33 = #8, (#7 - #8) [2,0,0]
// CHECK-LABEL: Decision,File 0, 8:17 -> 8:38 = M:4, C:5
// CHECK-LABEL: Decision,File 0, 8:17 -> 8:38 = M:18, C:5
// CHECK-NEXT: Branch,File 0, 8:17 -> 8:18 = #19, (#0 - #19) [1,5,0]
// CHECK: Branch,File 0, 8:22 -> 8:23 = #20, (#19 - #20) [5,4,0]
// CHECK: Branch,File 0, 8:27 -> 8:28 = #18, (#17 - #18) [4,3,0]
// CHECK: Branch,File 0, 8:32 -> 8:33 = #16, (#15 - #16) [3,2,0]
// CHECK: Branch,File 0, 8:37 -> 8:38 = #14, (#13 - #14) [2,0,0]
// CHECK-LABEL: Decision,File 0, 9:17 -> 9:43 = M:8, C:6
// CHECK-LABEL: Decision,File 0, 9:17 -> 9:43 = M:25, C:6
// CHECK-NEXT: Branch,File 0, 9:17 -> 9:18 = #29, (#0 - #29) [1,6,0]
// CHECK: Branch,File 0, 9:22 -> 9:23 = #30, (#29 - #30) [6,5,0]
// CHECK: Branch,File 0, 9:27 -> 9:28 = #28, (#27 - #28) [5,4,0]
Expand All @@ -45,25 +45,25 @@ bool func_scalar_or(bool a, bool b, bool c, bool d, bool e, bool f) {
return bar(res1, res2, res3, res4, res5);
}

// CHECK-LABEL: Decision,File 0, 40:17 -> 40:23 = M:0, C:2
// CHECK-LABEL: Decision,File 0, 40:17 -> 40:23 = M:3, C:2
// CHECK-NEXT: Branch,File 0, 40:17 -> 40:18 = (#0 - #1), #1 [1,0,2]
// CHECK: Branch,File 0, 40:22 -> 40:23 = (#1 - #2), #2 [2,0,0]
// CHECK-LABEL: Decision,File 0, 41:17 -> 41:28 = M:1, C:3
// CHECK-LABEL: Decision,File 0, 41:17 -> 41:28 = M:7, C:3
// CHECK-NEXT: Branch,File 0, 41:17 -> 41:18 = (#0 - #5), #5 [1,0,3]
// CHECK: Branch,File 0, 41:22 -> 41:23 = (#5 - #6), #6 [3,0,2]
// CHECK: Branch,File 0, 41:27 -> 41:28 = (#3 - #4), #4 [2,0,0]
// CHECK-LABEL: Decision,File 0, 42:17 -> 42:33 = M:2, C:4
// CHECK-LABEL: Decision,File 0, 42:17 -> 42:33 = M:12, C:4
// CHECK-NEXT: Branch,File 0, 42:17 -> 42:18 = (#0 - #11), #11 [1,0,4]
// CHECK: Branch,File 0, 42:22 -> 42:23 = (#11 - #12), #12 [4,0,3]
// CHECK: Branch,File 0, 42:27 -> 42:28 = (#9 - #10), #10 [3,0,2]
// CHECK: Branch,File 0, 42:32 -> 42:33 = (#7 - #8), #8 [2,0,0]
// CHECK-LABEL: Decision,File 0, 43:17 -> 43:38 = M:4, C:5
// CHECK-LABEL: Decision,File 0, 43:17 -> 43:38 = M:18, C:5
// CHECK-NEXT: Branch,File 0, 43:17 -> 43:18 = (#0 - #19), #19 [1,0,5]
// CHECK: Branch,File 0, 43:22 -> 43:23 = (#19 - #20), #20 [5,0,4]
// CHECK: Branch,File 0, 43:27 -> 43:28 = (#17 - #18), #18 [4,0,3]
// CHECK: Branch,File 0, 43:32 -> 43:33 = (#15 - #16), #16 [3,0,2]
// CHECK: Branch,File 0, 43:37 -> 43:38 = (#13 - #14), #14 [2,0,0]
// CHECK-LABEL: Decision,File 0, 44:17 -> 44:43 = M:8, C:6
// CHECK-LABEL: Decision,File 0, 44:17 -> 44:43 = M:25, C:6
// CHECK-NEXT: Branch,File 0, 44:17 -> 44:18 = (#0 - #29), #29 [1,0,6]
// CHECK: Branch,File 0, 44:22 -> 44:23 = (#29 - #30), #30 [6,0,5]
// CHECK: Branch,File 0, 44:27 -> 44:28 = (#27 - #28), #28 [5,0,4]
Expand All @@ -81,26 +81,26 @@ bool func_scalar_mix(bool a, bool b, bool c, bool d, bool e, bool f) {
return bar(res1, res2, res3, res4, res5);
}

// CHECK-LABEL: Decision,File 0, 76:17 -> 76:23 = M:0, C:2
// CHECK-LABEL: Decision,File 0, 76:17 -> 76:23 = M:3, C:2
// CHECK-NEXT: Branch,File 0, 76:17 -> 76:18 = (#0 - #1), #1 [1,0,2]
// CHECK: Branch,File 0, 76:22 -> 76:23 = (#1 - #2), #2 [2,0,0]
// CHECK-LABEL: Decision,File 0, 77:17 -> 77:30 = M:1, C:3
// CHECK-LABEL: Decision,File 0, 77:17 -> 77:30 = M:7, C:3
// CHECK-NEXT: Branch,File 0, 77:17 -> 77:18 = #3, (#0 - #3) [1,2,0]
// CHECK: Branch,File 0, 77:23 -> 77:24 = (#3 - #4), #4 [2,0,3]
// CHECK: Branch,File 0, 77:28 -> 77:29 = (#4 - #5), #5 [3,0,0]
// CHECK-LABEL: Decision,File 0, 78:17 -> 78:37 = M:2, C:4
// CHECK-LABEL: Decision,File 0, 78:17 -> 78:37 = M:14, C:4
// CHECK-NEXT: File 0
// CHECK-NEXT: Branch,File 0, 78:18 -> 78:19 = (#0 - #7), #7 [1,2,3]
// CHECK: Branch,File 0, 78:23 -> 78:24 = (#7 - #8), #8 [3,2,0]
// CHECK: Branch,File 0, 78:30 -> 78:31 = (#6 - #9), #9 [2,0,4]
// CHECK: Branch,File 0, 78:35 -> 78:36 = (#9 - #10), #10 [4,0,0]
// CHECK-LABEL: Decision,File 0, 79:17 -> 79:42 = M:4, C:5
// CHECK-LABEL: Decision,File 0, 79:17 -> 79:42 = M:22, C:5
// CHECK-NEXT: Branch,File 0, 79:17 -> 79:18 = #12, (#0 - #12) [1,3,0]
// CHECK: Branch,File 0, 79:23 -> 79:24 = (#12 - #13), #13 [3,2,4]
// CHECK: Branch,File 0, 79:28 -> 79:29 = (#13 - #14), #14 [4,2,0]
// CHECK: Branch,File 0, 79:35 -> 79:36 = (#11 - #15), #15 [2,0,5]
// CHECK: Branch,File 0, 79:40 -> 79:41 = (#15 - #16), #16 [5,0,0]
// CHECK-LABEL: Decision,File 0, 80:17 -> 80:49 = M:8, C:6
// CHECK-LABEL: Decision,File 0, 80:17 -> 80:49 = M:37, C:6
// CHECK-NEXT: File 0
// CHECK-NEXT: Branch,File 0, 80:18 -> 80:19 = (#0 - #19), #19 [1,3,4]
// CHECK: Branch,File 0, 80:23 -> 80:24 = (#19 - #20), #20 [4,3,0]
Expand Down
32 changes: 16 additions & 16 deletions clang/test/CoverageMapping/mcdc-logical-stmt-ids-all.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ bool func_if_and(bool a, bool b, bool c, bool d, bool e, bool f) {
return false;
}

// CHECK-LABEL: Decision,File 0, 4:7 -> 4:33 = M:0, C:6
// CHECK-LABEL: Decision,File 0, 4:7 -> 4:33 = M:7, C:6
// CHECK-NEXT: Branch,File 0, 4:7 -> 4:8 = #10, (#0 - #10) [1,6,0]
// CHECK: Branch,File 0, 4:12 -> 4:13 = #11, (#10 - #11) [6,5,0]
// CHECK: Branch,File 0, 4:17 -> 4:18 = #9, (#8 - #9) [5,4,0]
Expand All @@ -20,7 +20,7 @@ bool func_if_or(bool a, bool b, bool c, bool d, bool e, bool f) {
return false;
}

// CHECK-LABEL: Decision,File 0, 18:7 -> 18:33 = M:0, C:6
// CHECK-LABEL: Decision,File 0, 18:7 -> 18:33 = M:7, C:6
// CHECK-NEXT: Branch,File 0, 18:7 -> 18:8 = (#0 - #10), #10 [1,0,6]
// CHECK: Branch,File 0, 18:12 -> 18:13 = (#10 - #11), #11 [6,0,5]
// CHECK: Branch,File 0, 18:17 -> 18:18 = (#8 - #9), #9 [5,0,4]
Expand All @@ -33,7 +33,7 @@ bool func_while_and(bool a, bool b, bool c, bool d, bool e, bool f) {
return false;
}

// CHECK-LABEL: Decision,File 0, 32:10 -> 32:36 = M:0, C:6
// CHECK-LABEL: Decision,File 0, 32:10 -> 32:36 = M:7, C:6
// CHECK-NEXT: Branch,File 0, 32:10 -> 32:11 = #10, (#0 - #10) [1,6,0]
// CHECK: Branch,File 0, 32:15 -> 32:16 = #11, (#10 - #11) [6,5,0]
// CHECK: Branch,File 0, 32:20 -> 32:21 = #9, (#8 - #9) [5,4,0]
Expand All @@ -46,7 +46,7 @@ bool func_while_or(bool a, bool b, bool c, bool d, bool e, bool f) {
return false;
}

// CHECK-LABEL: Decision,File 0, 45:10 -> 45:36 = M:0, C:6
// CHECK-LABEL: Decision,File 0, 45:10 -> 45:36 = M:7, C:6
// CHECK-NEXT: Branch,File 0, 45:10 -> 45:11 = (#0 - #10), #10 [1,0,6]
// CHECK: Branch,File 0, 45:15 -> 45:16 = (#10 - #11), #11 [6,0,5]
// CHECK: Branch,File 0, 45:20 -> 45:21 = (#8 - #9), #9 [5,0,4]
Expand All @@ -59,7 +59,7 @@ bool func_for_and(bool a, bool b, bool c, bool d, bool e, bool f) {
return false;
}

// CHECK-LABEL: Decision,File 0, 58:9 -> 58:35 = M:0, C:6
// CHECK-LABEL: Decision,File 0, 58:9 -> 58:35 = M:7, C:6
// CHECK-NEXT: Branch,File 0, 58:9 -> 58:10 = #10, (#0 - #10) [1,6,0]
// CHECK: Branch,File 0, 58:14 -> 58:15 = #11, (#10 - #11) [6,5,0]
// CHECK: Branch,File 0, 58:19 -> 58:20 = #9, (#8 - #9) [5,4,0]
Expand All @@ -72,7 +72,7 @@ bool func_for_or(bool a, bool b, bool c, bool d, bool e, bool f) {
return false;
}

// CHECK-LABEL: Decision,File 0, 71:9 -> 71:35 = M:0, C:6
// CHECK-LABEL: Decision,File 0, 71:9 -> 71:35 = M:7, C:6
// CHECK-NEXT: Branch,File 0, 71:9 -> 71:10 = (#0 - #10), #10 [1,0,6]
// CHECK: Branch,File 0, 71:14 -> 71:15 = (#10 - #11), #11 [6,0,5]
// CHECK: Branch,File 0, 71:19 -> 71:20 = (#8 - #9), #9 [5,0,4]
Expand All @@ -85,7 +85,7 @@ bool func_do_and(bool a, bool b, bool c, bool d, bool e, bool f) {
return false;
}

// CHECK-LABEL: Decision,File 0, 84:16 -> 84:42 = M:0, C:6
// CHECK-LABEL: Decision,File 0, 84:16 -> 84:42 = M:7, C:6
// CHECK-NEXT: Branch,File 0, 84:16 -> 84:17 = #10, ((#0 + #1) - #10) [1,6,0]
// CHECK: Branch,File 0, 84:21 -> 84:22 = #11, (#10 - #11) [6,5,0]
// CHECK: Branch,File 0, 84:26 -> 84:27 = #9, (#8 - #9) [5,4,0]
Expand All @@ -98,7 +98,7 @@ bool func_do_or(bool a, bool b, bool c, bool d, bool e, bool f) {
return false;
}

// CHECK-LABEL: Decision,File 0, 97:16 -> 97:42 = M:0, C:6
// CHECK-LABEL: Decision,File 0, 97:16 -> 97:42 = M:7, C:6
// CHECK-NEXT: Branch,File 0, 97:16 -> 97:17 = ((#0 + #1) - #10), #10 [1,0,6]
// CHECK: Branch,File 0, 97:21 -> 97:22 = (#10 - #11), #11 [6,0,5]
// CHECK: Branch,File 0, 97:26 -> 97:27 = (#8 - #9), #9 [5,0,4]
Expand All @@ -110,7 +110,7 @@ bool func_ternary_and(bool a, bool b, bool c, bool d, bool e, bool f) {
return (a && b && c && d && e && f) ? true : false;
}

// CHECK-LABEL: Decision,File 0, 110:11 -> 110:37 = M:0, C:6
// CHECK-LABEL: Decision,File 0, 110:11 -> 110:37 = M:7, C:6
// CHECK-NEXT: Branch,File 0, 110:11 -> 110:12 = #10, (#0 - #10) [1,6,0]
// CHECK: Branch,File 0, 110:16 -> 110:17 = #11, (#10 - #11) [6,5,0]
// CHECK: Branch,File 0, 110:21 -> 110:22 = #9, (#8 - #9) [5,4,0]
Expand All @@ -122,7 +122,7 @@ bool func_ternary_or(bool a, bool b, bool c, bool d, bool e, bool f) {
return (a || b || c || d || e || f) ? true : false;
}

// CHECK-LABEL: Decision,File 0, 122:11 -> 122:37 = M:0, C:6
// CHECK-LABEL: Decision,File 0, 122:11 -> 122:37 = M:7, C:6
// CHECK-NEXT: Branch,File 0, 122:11 -> 122:12 = (#0 - #10), #10 [1,0,6]
// CHECK: Branch,File 0, 122:16 -> 122:17 = (#10 - #11), #11 [6,0,5]
// CHECK: Branch,File 0, 122:21 -> 122:22 = (#8 - #9), #9 [5,0,4]
Expand All @@ -137,7 +137,7 @@ bool func_if_nested_if(bool a, bool b, bool c, bool d, bool e) {
return false;
}

// CHECK-LABEL: Decision,File 0, 134:7 -> 134:30 = M:0, C:5
// CHECK-LABEL: Decision,File 0, 134:7 -> 134:30 = M:8, C:5
// CHECK-NEXT: Branch,File 0, 134:7 -> 134:8 = (#0 - #6), #6 [1,0,4]
// CHECK: Branch,File 0, 134:13 -> 134:14 = #7, (#6 - #7) [4,5,3]
// CHECK: Branch,File 0, 134:18 -> 134:19 = #8, (#7 - #8) [5,0,3]
Expand All @@ -148,7 +148,7 @@ bool func_ternary_nested_if(bool a, bool b, bool c, bool d, bool e) {
return (a || (b && c) || d || e) ? true : false;
}

// CHECK-LABEL: Decision,File 0, 148:11 -> 148:34 = M:0, C:5
// CHECK-LABEL: Decision,File 0, 148:11 -> 148:34 = M:8, C:5
// CHECK-NEXT: Branch,File 0, 148:11 -> 148:12 = (#0 - #6), #6 [1,0,4]
// CHECK: Branch,File 0, 148:17 -> 148:18 = #7, (#6 - #7) [4,5,3]
// CHECK: Branch,File 0, 148:22 -> 148:23 = #8, (#7 - #8) [5,0,3]
Expand All @@ -162,7 +162,7 @@ bool func_if_nested_if_2(bool a, bool b, bool c, bool d, bool e) {
return false;
}

// CHECK-LABEL: Decision,File 0, 159:7 -> 159:32 = M:0, C:5
// CHECK-LABEL: Decision,File 0, 159:7 -> 159:32 = M:9, C:5
// CHECK-NEXT: Branch,File 0, 159:7 -> 159:8 = (#0 - #2), #2 [1,0,2]
// CHECK: Branch,File 0, 159:14 -> 159:15 = #7, (#2 - #7) [2,5,4]
// CHECK: Branch,File 0, 159:19 -> 159:20 = #8, (#7 - #8) [5,3,4]
Expand All @@ -173,7 +173,7 @@ bool func_ternary_nested_if_2(bool a, bool b, bool c, bool d, bool e) {
return (a || ((b && c) || d) && e) ? true : false;
}

// CHECK-LABEL: Decision,File 0, 173:11 -> 173:36 = M:0, C:5
// CHECK-LABEL: Decision,File 0, 173:11 -> 173:36 = M:9, C:5
// CHECK-NEXT: Branch,File 0, 173:11 -> 173:12 = (#0 - #2), #2 [1,0,2]
// CHECK: Branch,File 0, 173:18 -> 173:19 = #7, (#2 - #7) [2,5,4]
// CHECK: Branch,File 0, 173:23 -> 173:24 = #8, (#7 - #8) [5,3,4]
Expand All @@ -187,7 +187,7 @@ bool func_if_nested_if_3(bool a, bool b, bool c, bool d, bool e, bool f) {
return false;
}

// CHECK-LABEL: Decision,File 0, 184:7 -> 184:39 = M:0, C:6
// CHECK-LABEL: Decision,File 0, 184:7 -> 184:39 = M:12, C:6
// CHECK: Branch,File 0, 184:8 -> 184:9 = #5, (#0 - #5) [1,4,3]
// CHECK: Branch,File 0, 184:14 -> 184:15 = (#5 - #6), #6 [4,2,5]
// CHECK: Branch,File 0, 184:19 -> 184:20 = (#6 - #7), #7 [5,2,3]
Expand All @@ -199,7 +199,7 @@ bool func_ternary_nested_if_3(bool a, bool b, bool c, bool d, bool e, bool f) {
return ((a && (b || c) || (d && e)) && f) ? true : false;
}

// CHECK-LABEL: Decision,File 0, 199:11 -> 199:43 = M:0, C:6
// CHECK-LABEL: Decision,File 0, 199:11 -> 199:43 = M:12, C:6
// CHECK: Branch,File 0, 199:12 -> 199:13 = #5, (#0 - #5) [1,4,3]
// CHECK: Branch,File 0, 199:18 -> 199:19 = (#5 - #6), #6 [4,2,5]
// CHECK: Branch,File 0, 199:23 -> 199:24 = (#6 - #7), #7 [5,2,3]
Expand Down
30 changes: 15 additions & 15 deletions clang/test/CoverageMapping/mcdc-logical-stmt-ids.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,25 @@ bool func_if_and(bool a, bool b, bool c, bool d, bool e, bool f) {
return false;
}

// CHECK-LABEL: Decision,File 0, 4:7 -> 4:13 = M:0, C:2
// CHECK-LABEL: Decision,File 0, 4:7 -> 4:13 = M:3, C:2
// CHECK-NEXT: Branch,File 0, 4:7 -> 4:8 = #2, (#0 - #2) [1,2,0]
// CHECK: Branch,File 0, 4:12 -> 4:13 = #3, (#2 - #3) [2,0,0]
// CHECK-LABEL: Decision,File 0, 5:9 -> 5:20 = M:1, C:3
// CHECK-LABEL: Decision,File 0, 5:9 -> 5:20 = M:7, C:3
// CHECK-NEXT: Branch,File 0, 5:9 -> 5:10 = #7, (#1 - #7) [1,3,0]
// CHECK: Branch,File 0, 5:14 -> 5:15 = #8, (#7 - #8) [3,2,0]
// CHECK: Branch,File 0, 5:19 -> 5:20 = #6, (#5 - #6) [2,0,0]
// CHECK-LABEL: Decision,File 0, 6:11 -> 6:27 = M:2, C:4
// CHECK-LABEL: Decision,File 0, 6:11 -> 6:27 = M:12, C:4
// CHECK-NEXT: Branch,File 0, 6:11 -> 6:12 = #14, (#4 - #14) [1,4,0]
// CHECK: Branch,File 0, 6:16 -> 6:17 = #15, (#14 - #15) [4,3,0]
// CHECK: Branch,File 0, 6:21 -> 6:22 = #13, (#12 - #13) [3,2,0]
// CHECK: Branch,File 0, 6:26 -> 6:27 = #11, (#10 - #11) [2,0,0]
// CHECK-LABEL: Decision,File 0, 7:13 -> 7:34 = M:4, C:5
// CHECK-LABEL: Decision,File 0, 7:13 -> 7:34 = M:18, C:5
// CHECK-NEXT: Branch,File 0, 7:13 -> 7:14 = #23, (#9 - #23) [1,5,0]
// CHECK: Branch,File 0, 7:18 -> 7:19 = #24, (#23 - #24) [5,4,0]
// CHECK: Branch,File 0, 7:23 -> 7:24 = #22, (#21 - #22) [4,3,0]
// CHECK: Branch,File 0, 7:28 -> 7:29 = #20, (#19 - #20) [3,2,0]
// CHECK: Branch,File 0, 7:33 -> 7:34 = #18, (#17 - #18) [2,0,0]
// CHECK-LABEL: Decision,File 0, 8:16 -> 8:42 = M:8, C:6
// CHECK-LABEL: Decision,File 0, 8:16 -> 8:42 = M:25, C:6
// CHECK-NEXT: Branch,File 0, 8:16 -> 8:17 = #34, (#16 - #34) [1,6,0]
// CHECK: Branch,File 0, 8:21 -> 8:22 = #35, (#34 - #35) [6,5,0]
// CHECK: Branch,File 0, 8:26 -> 8:27 = #33, (#32 - #33) [5,4,0]
Expand All @@ -46,25 +46,25 @@ bool func_if_or(bool a, bool b, bool c, bool d, bool e, bool f) {
return false;
}

// CHECK-LABEL: Decision,File 0, 40:7 -> 40:13 = M:0, C:2
// CHECK-LABEL: Decision,File 0, 40:7 -> 40:13 = M:3, C:2
// CHECK-NEXT: Branch,File 0, 40:7 -> 40:8 = (#0 - #2), #2 [1,0,2]
// CHECK: Branch,File 0, 40:12 -> 40:13 = (#2 - #3), #3 [2,0,0]
// CHECK-LABEL: Decision,File 0, 41:9 -> 41:20 = M:1, C:3
// CHECK-LABEL: Decision,File 0, 41:9 -> 41:20 = M:7, C:3
// CHECK-NEXT: Branch,File 0, 41:9 -> 41:10 = (#1 - #7), #7 [1,0,3]
// CHECK: Branch,File 0, 41:14 -> 41:15 = (#7 - #8), #8 [3,0,2]
// CHECK: Branch,File 0, 41:19 -> 41:20 = (#5 - #6), #6 [2,0,0]
// CHECK-LABEL: Decision,File 0, 42:11 -> 42:27 = M:2, C:4
// CHECK-LABEL: Decision,File 0, 42:11 -> 42:27 = M:12, C:4
// CHECK-NEXT: Branch,File 0, 42:11 -> 42:12 = (#4 - #14), #14 [1,0,4]
// CHECK: Branch,File 0, 42:16 -> 42:17 = (#14 - #15), #15 [4,0,3]
// CHECK: Branch,File 0, 42:21 -> 42:22 = (#12 - #13), #13 [3,0,2]
// CHECK: Branch,File 0, 42:26 -> 42:27 = (#10 - #11), #11 [2,0,0]
// CHECK-LABEL: Decision,File 0, 43:13 -> 43:34 = M:4, C:5
// CHECK-LABEL: Decision,File 0, 43:13 -> 43:34 = M:18, C:5
// CHECK-NEXT: Branch,File 0, 43:13 -> 43:14 = (#9 - #23), #23 [1,0,5]
// CHECK: Branch,File 0, 43:18 -> 43:19 = (#23 - #24), #24 [5,0,4]
// CHECK: Branch,File 0, 43:23 -> 43:24 = (#21 - #22), #22 [4,0,3]
// CHECK: Branch,File 0, 43:28 -> 43:29 = (#19 - #20), #20 [3,0,2]
// CHECK: Branch,File 0, 43:33 -> 43:34 = (#17 - #18), #18 [2,0,0]
// CHECK-LABEL: Decision,File 0, 44:16 -> 44:42 = M:8, C:6
// CHECK-LABEL: Decision,File 0, 44:16 -> 44:42 = M:25, C:6
// CHECK-NEXT: Branch,File 0, 44:16 -> 44:17 = (#16 - #34), #34 [1,0,6]
// CHECK: Branch,File 0, 44:21 -> 44:22 = (#34 - #35), #35 [6,0,5]
// CHECK: Branch,File 0, 44:26 -> 44:27 = (#32 - #33), #33 [5,0,4]
Expand All @@ -82,26 +82,26 @@ bool func_if_mix(bool a, bool b, bool c, bool d, bool e, bool f) {
return false;
}

// CHECK-LABEL: Decision,File 0, 76:7 -> 76:13 = M:0, C:2
// CHECK-LABEL: Decision,File 0, 76:7 -> 76:13 = M:3, C:2
// CHECK-NEXT: Branch,File 0, 76:7 -> 76:8 = (#0 - #2), #2 [1,0,2]
// CHECK: Branch,File 0, 76:12 -> 76:13 = (#2 - #3), #3 [2,0,0]
// CHECK-LABEL: Decision,File 0, 77:9 -> 77:22 = M:1, C:3
// CHECK-LABEL: Decision,File 0, 77:9 -> 77:22 = M:7, C:3
// CHECK-NEXT: Branch,File 0, 77:9 -> 77:10 = #5, (#1 - #5) [1,2,0]
// CHECK: Branch,File 0, 77:15 -> 77:16 = (#5 - #6), #6 [2,0,3]
// CHECK: Branch,File 0, 77:20 -> 77:21 = (#6 - #7), #7 [3,0,0]
// CHECK-LABEL: Decision,File 0, 78:11 -> 78:31 = M:2, C:4
// CHECK-LABEL: Decision,File 0, 78:11 -> 78:31 = M:14, C:4
// CHECK-NEXT: File 0
// CHECK-NEXT: Branch,File 0, 78:12 -> 78:13 = (#4 - #10), #10 [1,2,3]
// CHECK: Branch,File 0, 78:17 -> 78:18 = (#10 - #11), #11 [3,2,0]
// CHECK: Branch,File 0, 78:24 -> 78:25 = (#9 - #12), #12 [2,0,4]
// CHECK: Branch,File 0, 78:29 -> 78:30 = (#12 - #13), #13 [4,0,0]
// CHECK-LABEL: Decision,File 0, 79:13 -> 79:38 = M:4, C:5
// CHECK-LABEL: Decision,File 0, 79:13 -> 79:38 = M:22, C:5
// CHECK-NEXT: Branch,File 0, 79:13 -> 79:14 = #16, (#8 - #16) [1,3,0]
// CHECK: Branch,File 0, 79:19 -> 79:20 = (#16 - #17), #17 [3,2,4]
// CHECK: Branch,File 0, 79:24 -> 79:25 = (#17 - #18), #18 [4,2,0]
// CHECK: Branch,File 0, 79:31 -> 79:32 = (#15 - #19), #19 [2,0,5]
// CHECK: Branch,File 0, 79:36 -> 79:37 = (#19 - #20), #20 [5,0,0]
// CHECK-LABEL: Decision,File 0, 80:15 -> 80:47 = M:8, C:6
// CHECK-LABEL: Decision,File 0, 80:15 -> 80:47 = M:37, C:6
// CHECK-NEXT: File 0
// CHECK-NEXT: Branch,File 0, 80:16 -> 80:17 = (#14 - #24), #24 [1,3,4]
// CHECK: Branch,File 0, 80:21 -> 80:22 = (#24 - #25), #25 [4,3,0]
Expand Down
12 changes: 6 additions & 6 deletions clang/test/CoverageMapping/mcdc-scratch-space.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

// CHECK: builtin_macro0:
int builtin_macro0(int a) {
// CHECK: Decision,File 0, [[@LINE+1]]:11 -> [[@LINE+2]]:15 = M:0, C:2
// CHECK: Decision,File 0, [[@LINE+1]]:11 -> [[@LINE+2]]:15 = M:3, C:2
return (__LINE__ // CHECK: Branch,File 0, [[@LINE]]:11 -> [[@LINE]]:11 = 0, 0 [1,2,0]
&& a); // CHECK: Branch,File 0, [[@LINE]]:14 -> [[@LINE]]:15 = #2, (#1 - #2) [2,0,0]
}

// CHECK: builtin_macro1:
int builtin_macro1(int a) {
// CHECK: Decision,File 0, [[@LINE+1]]:11 -> [[@LINE+2]]:22 = M:0, C:2
// CHECK: Decision,File 0, [[@LINE+1]]:11 -> [[@LINE+2]]:22 = M:3, C:2
return (a // CHECK: Branch,File 0, [[@LINE]]:11 -> [[@LINE]]:12 = (#0 - #1), #1 [1,0,2]
|| __LINE__); // CHECK: Branch,File 0, [[@LINE]]:14 -> [[@LINE]]:14 = 0, 0 [2,0,0]
}
Expand All @@ -18,7 +18,7 @@ int builtin_macro1(int a) {

// CHECK: pre0:
int pre0(int pre_a, int b_post) {
// CHECK: Decision,File 0, [[@LINE+2]]:11 -> [[@LINE+3]]:20 = M:0, C:2
// CHECK: Decision,File 0, [[@LINE+2]]:11 -> [[@LINE+3]]:20 = M:3, C:2
// CHECK: Expansion,File 0, [[@LINE+1]]:11 -> [[@LINE+1]]:14 = #0 (Expanded file = 1)
return (PRE(a)
&& b_post);
Expand All @@ -30,7 +30,7 @@ int pre0(int pre_a, int b_post) {

// CHECK: pre1:
int pre1(int pre_a, int b_post) {
// CHECK: Decision,File 0, [[@LINE+3]]:11 -> [[@LINE+4]]:20 = M:0, C:2
// CHECK: Decision,File 0, [[@LINE+3]]:11 -> [[@LINE+4]]:20 = M:3, C:2
// CHECK: Expansion,File 0, [[@LINE+2]]:11 -> [[@LINE+2]]:14 = #0 (Expanded file = 1)
// CHECK: Branch,File 0, [[@LINE+2]]:14 -> [[@LINE+2]]:20 = #2, (#1 - #2) [2,0,0]
return (PRE(foo)
Expand All @@ -43,7 +43,7 @@ int pre1(int pre_a, int b_post) {

// CHECK: post0:
int post0(int pre_a, int b_post) {
// CHECK: Decision,File 0, [[@LINE+2]]:11 -> [[@LINE+3]]:18 = M:0, C:2
// CHECK: Decision,File 0, [[@LINE+2]]:11 -> [[@LINE+3]]:18 = M:3, C:2
// CHECK: Branch,File 0, [[@LINE+1]]:11 -> [[@LINE+1]]:16 = (#0 - #1), #1 [1,0,2]
return (pre_a
|| POST(b));
Expand All @@ -55,7 +55,7 @@ int post0(int pre_a, int b_post) {

// CHECK: post1:
int post1(int pre_a, int b_post) {
// CHECK: Decision,File 0, [[@LINE+3]]:11 -> [[@LINE+4]]:18 = M:0, C:2
// CHECK: Decision,File 0, [[@LINE+3]]:11 -> [[@LINE+4]]:18 = M:3, C:2
// CHECK: Branch,File 0, [[@LINE+2]]:11 -> [[@LINE+2]]:16 = (#0 - #1), #1 [1,0,2]
// CHECK: Expansion,File 0, [[@LINE+2]]:14 -> [[@LINE+2]]:18 = 0 (Expanded file = 1)
return (pre_a
Expand Down
8 changes: 4 additions & 4 deletions clang/test/CoverageMapping/mcdc-system-headers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

// CHECK: _Z5func0i:
int func0(int a) {
// CHECK: Decision,File 0, [[@LINE+3]]:11 -> [[@LINE+3]]:21 = M:0, C:2
// CHECK: Decision,File 0, [[@LINE+3]]:11 -> [[@LINE+3]]:21 = M:3, C:2
// W_SYS: Expansion,File 0, [[@LINE+2]]:11 -> [[@LINE+2]]:16 = #0 (Expanded file = 1)
// X_SYS: Branch,File 0, [[@LINE+1]]:11 -> [[@LINE+1]]:11 = 0, 0 [1,2,0]
return (CONST && a);
Expand All @@ -25,7 +25,7 @@ int func0(int a) {

// CHECK: _Z5func1ii:
int func1(int a, int b) {
// CHECK: Decision,File 0, [[@LINE+2]]:11 -> [[@LINE+2]]:21 = M:0, C:2
// CHECK: Decision,File 0, [[@LINE+2]]:11 -> [[@LINE+2]]:21 = M:3, C:2
// CHECK: Branch,File 0, [[@LINE+1]]:11 -> [[@LINE+1]]:12 = (#0 - #1), #1 [1,0,2]
return (a || EXPR1(b));
// W_SYS: Expansion,File 0, [[@LINE-1]]:16 -> [[@LINE-1]]:21 = #1 (Expanded file = 1)
Expand All @@ -35,8 +35,8 @@ int func1(int a, int b) {

// CHECK: _Z5func2ii:
int func2(int a, int b) {
// W_SYS: Decision,File 0, [[@LINE+5]]:11 -> [[@LINE+5]]:28 = M:0, C:3
// X_SYS: Decision,File 0, [[@LINE+4]]:11 -> [[@LINE+4]]:28 = M:0, C:2
// W_SYS: Decision,File 0, [[@LINE+5]]:11 -> [[@LINE+5]]:28 = M:4, C:3
// X_SYS: Decision,File 0, [[@LINE+4]]:11 -> [[@LINE+4]]:28 = M:3, C:2
// W_SYS: Expansion,File 0, [[@LINE+3]]:11 -> [[@LINE+3]]:16 = #0 (Expanded file = 1)
// W_SYS: Expansion,File 0, [[@LINE+2]]:23 -> [[@LINE+2]]:28 = #1 (Expanded file = 2)
// X_SYS: Branch,File 0, [[@LINE+1]]:11 -> [[@LINE+1]]:11 = #1, (#0 - #1) [1,2,0]
Expand Down
27 changes: 26 additions & 1 deletion clang/test/Driver/debug-options.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,32 @@
// RUN: %clang -### -c -g %s -target x86_64-apple-driverkit19.0 2>&1 \
// RUN: | FileCheck -check-prefix=G_STANDALONE \
// RUN: -check-prefix=G_DWARF4 %s
// RUN: %clang -### -c -fsave-optimization-record %s \
// RUN: %clang -### -c -g %s -target x86_64-apple-macosx15 2>&1 \
// RUN: | FileCheck -check-prefix=G_STANDALONE \
// RUN: -check-prefix=G_DWARF5 %s
// RUN: %clang -### -c -g %s -target arm64-apple-ios17.0 2>&1 \
// RUN: | FileCheck -check-prefix=G_STANDALONE \
// RUN: -check-prefix=G_DWARF4 %s
// RUN: %clang -### -c -g %s -target arm64-apple-ios18.0 2>&1 \
// RUN: | FileCheck -check-prefix=G_STANDALONE \
// RUN: -check-prefix=G_DWARF5 %s
// RUN: %clang -### -c -g %s -target arm64_32-apple-watchos11 2>&1 \
// RUN: | FileCheck -check-prefix=G_STANDALONE \
// RUN: -check-prefix=G_DWARF5 %s
// RUN: %clang -### -c -g %s -target arm64-apple-tvos18.0 2>&1 \
// RUN: | FileCheck -check-prefix=G_STANDALONE \
// RUN: -check-prefix=G_DWARF5 %s
// RUN: %clang -### -c -g %s -target x86_64-apple-driverkit24.0 2>&1 \
// RUN: | FileCheck -check-prefix=G_STANDALONE \
// RUN: -check-prefix=G_DWARF5 %s
// RUN: %clang -### -c -g %s -target arm64-apple-xros1 2>&1 \
// RUN: | FileCheck -check-prefix=G_STANDALONE \
// RUN: -check-prefix=G_DWARF4 %s
// RUN: %clang -### -c -g %s -target arm64-apple-xros2 2>&1 \
// RUN: | FileCheck -check-prefix=G_STANDALONE \
// RUN: -check-prefix=G_DWARF5 %s
//
// RUN: %clang -### -c -fsave-optimization-record %s \
// RUN: -target x86_64-apple-darwin 2>&1 \
// RUN: | FileCheck -check-prefix=GLTO_ONLY %s
// RUN: %clang -### -c -g -fsave-optimization-record %s \
Expand Down
9 changes: 7 additions & 2 deletions clang/test/Driver/spirv-toolchain.cl
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,15 @@

//-----------------------------------------------------------------------------
// Check llvm-spirv-<LLVM_VERSION_MAJOR> is used if it is found in PATH.
//
// This test uses the PATH environment variable; on Windows, we may need to retain
// the original path for the built Clang binary to be able to execute (as it is
// used for locating dependent DLLs). Therefore, skip this test on system-windows.
//
// RUN: mkdir -p %t/versioned
// RUN: touch %t/versioned/llvm-spirv-%llvm-version-major \
// RUN: && chmod +x %t/versioned/llvm-spirv-%llvm-version-major
// RUN: env "PATH=%t/versioned" %clang -### --target=spirv64 -x cl -c %s 2>&1 \
// RUN: | FileCheck -DVERSION=%llvm-version-major --check-prefix=VERSIONED %s
// RUN: %if !system-windows %{ env "PATH=%t/versioned" %clang -### --target=spirv64 -x cl -c %s 2>&1 \
// RUN: | FileCheck -DVERSION=%llvm-version-major --check-prefix=VERSIONED %s %}

// VERSIONED: {{.*}}llvm-spirv-[[VERSION]]
4 changes: 4 additions & 0 deletions clang/test/Lexer/cxx2c-raw-strings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,8 @@ int main() {
(void) R"\()\";
// expected-error@-1 {{invalid character '\' in raw string delimiter}}
// expected-error@-2 {{expected expression}}
(void) R"@(foo)@";
// cxx26-warning@-1 {{'@' in a raw string literal delimiter is incompatible with standards before C++2c}}
// precxx26-warning@-2 {{'@' in a raw string literal delimiter is a C++2c extension}}
}
16 changes: 8 additions & 8 deletions clang/test/OpenMP/threadprivate_codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2586,7 +2586,7 @@ int foobar() {
// SIMD1-NEXT: [[TMP12:%.*]] = load i32, ptr [[RES]], align 4
// SIMD1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP12]], [[TMP11]]
// SIMD1-NEXT: store i32 [[ADD3]], ptr [[RES]], align 4
// SIMD1-NEXT: [[TMP13:%.*]] = load i32, ptr getelementptr inbounds ([2 x [3 x %struct.S1]], ptr @arr_x, i64 0, i64 1, i64 1), align 4
// SIMD1-NEXT: [[TMP13:%.*]] = load i32, ptr getelementptr inbounds ([3 x %struct.S1], ptr getelementptr inbounds ([2 x [3 x %struct.S1]], ptr @arr_x, i64 0, i64 1), i64 0, i64 1), align 4
// SIMD1-NEXT: [[TMP14:%.*]] = load i32, ptr [[RES]], align 4
// SIMD1-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP14]], [[TMP13]]
// SIMD1-NEXT: store i32 [[ADD4]], ptr [[RES]], align 4
Expand Down Expand Up @@ -2663,7 +2663,7 @@ int foobar() {
// SIMD1-NEXT: [[TMP6:%.*]] = load i32, ptr [[RES]], align 4
// SIMD1-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP6]], [[TMP5]]
// SIMD1-NEXT: store i32 [[ADD2]], ptr [[RES]], align 4
// SIMD1-NEXT: [[TMP7:%.*]] = load i32, ptr getelementptr inbounds ([2 x [3 x %struct.S1]], ptr @arr_x, i64 0, i64 1, i64 1), align 4
// SIMD1-NEXT: [[TMP7:%.*]] = load i32, ptr getelementptr inbounds ([3 x %struct.S1], ptr getelementptr inbounds ([2 x [3 x %struct.S1]], ptr @arr_x, i64 0, i64 1), i64 0, i64 1), align 4
// SIMD1-NEXT: [[TMP8:%.*]] = load i32, ptr [[RES]], align 4
// SIMD1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP8]], [[TMP7]]
// SIMD1-NEXT: store i32 [[ADD3]], ptr [[RES]], align 4
Expand Down Expand Up @@ -3052,7 +3052,7 @@ int foobar() {
// SIMD2-NEXT: [[TMP12:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG187:![0-9]+]]
// SIMD2-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP12]], [[TMP11]], !dbg [[DBG187]]
// SIMD2-NEXT: store i32 [[ADD3]], ptr [[RES]], align 4, !dbg [[DBG187]]
// SIMD2-NEXT: [[TMP13:%.*]] = load i32, ptr getelementptr inbounds ([2 x [3 x %struct.S1]], ptr @arr_x, i64 0, i64 1, i64 1), align 4, !dbg [[DBG188:![0-9]+]]
// SIMD2-NEXT: [[TMP13:%.*]] = load i32, ptr getelementptr inbounds ([3 x %struct.S1], ptr getelementptr inbounds ([2 x [3 x %struct.S1]], ptr @arr_x, i64 0, i64 1), i64 0, i64 1), align 4, !dbg [[DBG188:![0-9]+]]
// SIMD2-NEXT: [[TMP14:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG189:![0-9]+]]
// SIMD2-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP14]], [[TMP13]], !dbg [[DBG189]]
// SIMD2-NEXT: store i32 [[ADD4]], ptr [[RES]], align 4, !dbg [[DBG189]]
Expand Down Expand Up @@ -3133,7 +3133,7 @@ int foobar() {
// SIMD2-NEXT: [[TMP6:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG222:![0-9]+]]
// SIMD2-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP6]], [[TMP5]], !dbg [[DBG222]]
// SIMD2-NEXT: store i32 [[ADD2]], ptr [[RES]], align 4, !dbg [[DBG222]]
// SIMD2-NEXT: [[TMP7:%.*]] = load i32, ptr getelementptr inbounds ([2 x [3 x %struct.S1]], ptr @arr_x, i64 0, i64 1, i64 1), align 4, !dbg [[DBG223:![0-9]+]]
// SIMD2-NEXT: [[TMP7:%.*]] = load i32, ptr getelementptr inbounds ([3 x %struct.S1], ptr getelementptr inbounds ([2 x [3 x %struct.S1]], ptr @arr_x, i64 0, i64 1), i64 0, i64 1), align 4, !dbg [[DBG223:![0-9]+]]
// SIMD2-NEXT: [[TMP8:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG224:![0-9]+]]
// SIMD2-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP8]], [[TMP7]], !dbg [[DBG224]]
// SIMD2-NEXT: store i32 [[ADD3]], ptr [[RES]], align 4, !dbg [[DBG224]]
Expand Down Expand Up @@ -5707,7 +5707,7 @@ int foobar() {
// SIMD3-NEXT: [[TMP12:%.*]] = load i32, ptr [[RES]], align 4
// SIMD3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP12]], [[TMP11]]
// SIMD3-NEXT: store i32 [[ADD3]], ptr [[RES]], align 4
// SIMD3-NEXT: [[TMP13:%.*]] = load i32, ptr getelementptr inbounds ([2 x [3 x %struct.S1]], ptr @arr_x, i64 0, i64 1, i64 1), align 4
// SIMD3-NEXT: [[TMP13:%.*]] = load i32, ptr getelementptr inbounds ([3 x %struct.S1], ptr getelementptr inbounds ([2 x [3 x %struct.S1]], ptr @arr_x, i64 0, i64 1), i64 0, i64 1), align 4
// SIMD3-NEXT: [[TMP14:%.*]] = load i32, ptr [[RES]], align 4
// SIMD3-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP14]], [[TMP13]]
// SIMD3-NEXT: store i32 [[ADD4]], ptr [[RES]], align 4
Expand Down Expand Up @@ -5784,7 +5784,7 @@ int foobar() {
// SIMD3-NEXT: [[TMP6:%.*]] = load i32, ptr [[RES]], align 4
// SIMD3-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP6]], [[TMP5]]
// SIMD3-NEXT: store i32 [[ADD2]], ptr [[RES]], align 4
// SIMD3-NEXT: [[TMP7:%.*]] = load i32, ptr getelementptr inbounds ([2 x [3 x %struct.S1]], ptr @arr_x, i64 0, i64 1, i64 1), align 4
// SIMD3-NEXT: [[TMP7:%.*]] = load i32, ptr getelementptr inbounds ([3 x %struct.S1], ptr getelementptr inbounds ([2 x [3 x %struct.S1]], ptr @arr_x, i64 0, i64 1), i64 0, i64 1), align 4
// SIMD3-NEXT: [[TMP8:%.*]] = load i32, ptr [[RES]], align 4
// SIMD3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP8]], [[TMP7]]
// SIMD3-NEXT: store i32 [[ADD3]], ptr [[RES]], align 4
Expand Down Expand Up @@ -6173,7 +6173,7 @@ int foobar() {
// SIMD4-NEXT: [[TMP12:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG187:![0-9]+]]
// SIMD4-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP12]], [[TMP11]], !dbg [[DBG187]]
// SIMD4-NEXT: store i32 [[ADD3]], ptr [[RES]], align 4, !dbg [[DBG187]]
// SIMD4-NEXT: [[TMP13:%.*]] = load i32, ptr getelementptr inbounds ([2 x [3 x %struct.S1]], ptr @arr_x, i64 0, i64 1, i64 1), align 4, !dbg [[DBG188:![0-9]+]]
// SIMD4-NEXT: [[TMP13:%.*]] = load i32, ptr getelementptr inbounds ([3 x %struct.S1], ptr getelementptr inbounds ([2 x [3 x %struct.S1]], ptr @arr_x, i64 0, i64 1), i64 0, i64 1), align 4, !dbg [[DBG188:![0-9]+]]
// SIMD4-NEXT: [[TMP14:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG189:![0-9]+]]
// SIMD4-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP14]], [[TMP13]], !dbg [[DBG189]]
// SIMD4-NEXT: store i32 [[ADD4]], ptr [[RES]], align 4, !dbg [[DBG189]]
Expand Down Expand Up @@ -6254,7 +6254,7 @@ int foobar() {
// SIMD4-NEXT: [[TMP6:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG222:![0-9]+]]
// SIMD4-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP6]], [[TMP5]], !dbg [[DBG222]]
// SIMD4-NEXT: store i32 [[ADD2]], ptr [[RES]], align 4, !dbg [[DBG222]]
// SIMD4-NEXT: [[TMP7:%.*]] = load i32, ptr getelementptr inbounds ([2 x [3 x %struct.S1]], ptr @arr_x, i64 0, i64 1, i64 1), align 4, !dbg [[DBG223:![0-9]+]]
// SIMD4-NEXT: [[TMP7:%.*]] = load i32, ptr getelementptr inbounds ([3 x %struct.S1], ptr getelementptr inbounds ([2 x [3 x %struct.S1]], ptr @arr_x, i64 0, i64 1), i64 0, i64 1), align 4, !dbg [[DBG223:![0-9]+]]
// SIMD4-NEXT: [[TMP8:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG224:![0-9]+]]
// SIMD4-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP8]], [[TMP7]], !dbg [[DBG224]]
// SIMD4-NEXT: store i32 [[ADD3]], ptr [[RES]], align 4, !dbg [[DBG224]]
Expand Down
38 changes: 20 additions & 18 deletions clang/test/Profile/c-mcdc-class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,23 +36,24 @@ Value::~Value(void) {
// SHIFT FIRST CONDITION WITH ID = 0.
// MCDCCTOR: %[[LAB1:[0-9]+]] = load i32, ptr %value, align 4
// MCDCCTOR-DAG: %[[BOOL:cmp[0-9]*]] = icmp ne i32 %[[LAB1]], 2
// MCDCCTOR-DAG: %[[TEMP:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDCCTOR-DAG: %[[LAB2:[0-9]+]] = zext i1 %[[BOOL]] to i32
// MCDCCTOR-DAG: %[[LAB3:[0-9]+]] = shl i32 %[[LAB2]], 0
// MCDCCTOR-DAG: %[[LAB4:[0-9]+]] = or i32 %[[TEMP]], %[[LAB3]]
// MCDCCTOR-DAG: %[[TEMP:mcdc.*]] = load i32, ptr %mcdc.addr, align 4
// MCDCCTOR-DAG: %[[LAB2:[0-9]+]] = add i32 %[[TEMP]], 0
// MCDCCTOR-DAG: %[[LAB3:[0-9]+]] = add i32 %[[TEMP]], 0
// MCDCCTOR-DAG: %[[LAB4:[0-9]+]] = select i1 %[[BOOL]], i32 %[[LAB2]], i32 %[[LAB3]]
// MCDCCTOR-DAG: store i32 %[[LAB4]], ptr %mcdc.addr, align 4

// SHIFT SECOND CONDITION WITH ID = 1.
// MCDCCTOR: %[[LAB1:[0-9]+]] = load i32, ptr %value2, align 4
// MCDCCTOR-DAG: %[[BOOL:cmp[0-9]*]] = icmp ne i32 %[[LAB1]], 6
// MCDCCTOR-DAG: %[[TEMP:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDCCTOR-DAG: %[[LAB2:[0-9]+]] = zext i1 %[[BOOL]] to i32
// MCDCCTOR-DAG: %[[LAB3:[0-9]+]] = shl i32 %[[LAB2]], 1
// MCDCCTOR-DAG: %[[LAB4:[0-9]+]] = or i32 %[[TEMP]], %[[LAB3]]
// MCDCCTOR-DAG: %[[TEMP:mcdc.*]] = load i32, ptr %mcdc.addr, align 4
// MCDCCTOR-DAG: %[[LAB2:[0-9]+]] = add i32 %[[TEMP]], 2
// MCDCCTOR-DAG: %[[LAB3:[0-9]+]] = add i32 %[[TEMP]], 1
// MCDCCTOR-DAG: %[[LAB4:[0-9]+]] = select i1 %[[BOOL]], i32 %[[LAB2]], i32 %[[LAB3]]
// MCDCCTOR-DAG: store i32 %[[LAB4]], ptr %mcdc.addr, align 4

// UPDATE FINAL BITMASK WITH RESULT.
// MCDCCTOR-DAG: %[[TEMP:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDCCTOR-DAG: %[[TEMP0:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDCCTOR: %[[TEMP:[0-9]+]] = add i32 %[[TEMP0]], 0
// MCDCCTOR: %[[LAB1:[0-9]+]] = lshr i32 %[[TEMP]], 3
// MCDCCTOR: %[[LAB4:[0-9]+]] = getelementptr inbounds i8, ptr @__profbm__ZN5ValueC2Ev, i32 %[[LAB1]]
// MCDCCTOR: %[[LAB5:[0-9]+]] = and i32 %[[TEMP]], 7
Expand All @@ -73,23 +74,24 @@ Value::~Value(void) {
// SHIFT FIRST CONDITION WITH ID = 0.
// MCDCDTOR: %[[LAB1:[0-9]+]] = load i32, ptr %value, align 4
// MCDCDTOR-DAG: %[[BOOL:cmp[0-9]*]] = icmp ne i32 %[[LAB1]], 2
// MCDCDTOR-DAG: %[[TEMP:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDCDTOR-DAG: %[[LAB2:[0-9]+]] = zext i1 %[[BOOL]] to i32
// MCDCDTOR-DAG: %[[LAB3:[0-9]+]] = shl i32 %[[LAB2]], 0
// MCDCDTOR-DAG: %[[LAB4:[0-9]+]] = or i32 %[[TEMP]], %[[LAB3]]
// MCDCDTOR-DAG: %[[TEMP:mcdc.*]] = load i32, ptr %mcdc.addr, align 4
// MCDCDTOR-DAG: %[[LAB2:[0-9]+]] = add i32 %[[TEMP]], 0
// MCDCDTOR-DAG: %[[LAB3:[0-9]+]] = add i32 %[[TEMP]], 0
// MCDCDTOR-DAG: %[[LAB4:[0-9]+]] = select i1 %[[BOOL]], i32 %[[LAB2]], i32 %[[LAB3]]
// MCDCDTOR-DAG: store i32 %[[LAB4]], ptr %mcdc.addr, align 4

// SHIFT SECOND CONDITION WITH ID = 1.
// MCDCDTOR: %[[LAB1:[0-9]+]] = load i32, ptr %value2, align 4
// MCDCDTOR-DAG: %[[BOOL:cmp[0-9]*]] = icmp ne i32 %[[LAB1]], 3
// MCDCDTOR-DAG: %[[TEMP:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDCDTOR-DAG: %[[LAB2:[0-9]+]] = zext i1 %[[BOOL]] to i32
// MCDCDTOR-DAG: %[[LAB3:[0-9]+]] = shl i32 %[[LAB2]], 1
// MCDCDTOR-DAG: %[[LAB4:[0-9]+]] = or i32 %[[TEMP]], %[[LAB3]]
// MCDCDTOR-DAG: %[[TEMP:mcdc.*]] = load i32, ptr %mcdc.addr, align 4
// MCDCDTOR-DAG: %[[LAB2:[0-9]+]] = add i32 %[[TEMP]], 2
// MCDCDTOR-DAG: %[[LAB3:[0-9]+]] = add i32 %[[TEMP]], 1
// MCDCDTOR-DAG: %[[LAB4:[0-9]+]] = select i1 %[[BOOL]], i32 %[[LAB2]], i32 %[[LAB3]]
// MCDCDTOR-DAG: store i32 %[[LAB4]], ptr %mcdc.addr, align 4

// UPDATE FINAL BITMASK WITH RESULT.
// MCDCDTOR-DAG: %[[TEMP:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDCDTOR-DAG: %[[TEMP0:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDCDTOR: %[[TEMP:[0-9]+]] = add i32 %[[TEMP0]], 0
// MCDCDTOR: %[[LAB1:[0-9]+]] = lshr i32 %[[TEMP]], 3
// MCDCDTOR: %[[LAB4:[0-9]+]] = getelementptr inbounds i8, ptr @__profbm__ZN5ValueD2Ev, i32 %[[LAB1]]
// MCDCDTOR: %[[LAB5:[0-9]+]] = and i32 %[[TEMP]], 7
Expand Down
18 changes: 11 additions & 7 deletions clang/test/Profile/c-mcdc-logicalop-ternary.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ int test(int a, int b, int c, int d, int e, int f) {
// NOMCDC-NOT: __profbm_test

// MCDC BOOKKEEPING.
// MCDC: @__profbm_test = private global [3 x i8] zeroinitializer
// MCDC: @__profbm_test = private global [2 x i8] zeroinitializer

// ALLOCATE MCDC TEMP AND ZERO IT.
// MCDC-LABEL: @test(
Expand All @@ -18,7 +18,8 @@ int test(int a, int b, int c, int d, int e, int f) {

// TERNARY TRUE SHOULD UPDATE THE BITMAP WITH RESULT AT ELEMENT 0.
// MCDC-LABEL: cond.true:
// MCDC-DAG: %[[TEMP:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[TEMP0:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC: %[[TEMP:[0-9]+]] = add i32 %[[TEMP0]], 0
// MCDC: %[[LAB1:[0-9]+]] = lshr i32 %[[TEMP]], 3
// MCDC: %[[LAB4:[0-9]+]] = getelementptr inbounds i8, ptr @__profbm_test, i32 %[[LAB1]]
// MCDC: %[[LAB5:[0-9]+]] = and i32 %[[TEMP]], 7
Expand All @@ -34,9 +35,10 @@ int test(int a, int b, int c, int d, int e, int f) {
// TERNARY TRUE YIELDS TERNARY LHS LOGICAL-AND.
// TERNARY LHS LOGICAL-AND SHOULD UPDATE THE BITMAP WITH RESULT AT ELEMENT 1.
// MCDC-LABEL: land.end:
// MCDC-DAG: %[[TEMP:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[TEMP0:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC: %[[TEMP:[0-9]+]] = add i32 %[[TEMP0]], 3
// MCDC: %[[LAB1:[0-9]+]] = lshr i32 %[[TEMP]], 3
// MCDC: %[[LAB4:[0-9]+]] = getelementptr inbounds i8, ptr getelementptr inbounds ([3 x i8], ptr @__profbm_test, i32 0, i32 1), i32 %[[LAB1]]
// MCDC: %[[LAB4:[0-9]+]] = getelementptr inbounds i8, ptr @__profbm_test, i32 %[[LAB1]]
// MCDC: %[[LAB5:[0-9]+]] = and i32 %[[TEMP]], 7
// MCDC: %[[LAB6:[0-9]+]] = trunc i32 %[[LAB5]] to i8
// MCDC: %[[LAB7:[0-9]+]] = shl i8 1, %[[LAB6]]
Expand All @@ -46,7 +48,8 @@ int test(int a, int b, int c, int d, int e, int f) {

// TERNARY FALSE SHOULD UPDATE THE BITMAP WITH RESULT AT ELEMENT 0.
// MCDC-LABEL: cond.false:
// MCDC-DAG: %[[TEMP:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[TEMP0:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC: %[[TEMP:[0-9]+]] = add i32 %[[TEMP0]], 0
// MCDC: %[[LAB1:[0-9]+]] = lshr i32 %[[TEMP]], 3
// MCDC: %[[LAB4:[0-9]+]] = getelementptr inbounds i8, ptr @__profbm_test, i32 %[[LAB1]]
// MCDC: %[[LAB5:[0-9]+]] = and i32 %[[TEMP]], 7
Expand All @@ -62,9 +65,10 @@ int test(int a, int b, int c, int d, int e, int f) {
// TERNARY FALSE YIELDS TERNARY RHS LOGICAL-OR.
// TERNARY RHS LOGICAL-OR SHOULD UPDATE THE BITMAP WITH RESULT AT ELEMENT 2.
// MCDC-LABEL: lor.end:
// MCDC-DAG: %[[TEMP:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[TEMP0:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC: %[[TEMP:[0-9]+]] = add i32 %[[TEMP0]], 6
// MCDC: %[[LAB1:[0-9]+]] = lshr i32 %[[TEMP]], 3
// MCDC: %[[LAB4:[0-9]+]] = getelementptr inbounds i8, ptr getelementptr inbounds ([3 x i8], ptr @__profbm_test, i32 0, i32 2), i32 %[[LAB1]]
// MCDC: %[[LAB4:[0-9]+]] = getelementptr inbounds i8, ptr @__profbm_test, i32 %[[LAB1]]
// MCDC: %[[LAB5:[0-9]+]] = and i32 %[[TEMP]], 7
// MCDC: %[[LAB6:[0-9]+]] = trunc i32 %[[LAB5]] to i8
// MCDC: %[[LAB7:[0-9]+]] = shl i8 1, %[[LAB6]]
Expand Down
35 changes: 18 additions & 17 deletions clang/test/Profile/c-mcdc-nested-ternary.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,42 +20,43 @@ int test(int b, int c, int d, int e, int f) {
// MCDC-LABEL: cond.true:
// MCDC: %[[LAB1:[0-9]+]] = load i32, ptr %c.addr, align 4
// MCDC-DAG: %[[BOOL:tobool[0-9]*]] = icmp ne i32 %[[LAB1]], 0
// MCDC-DAG: %[[TEMP:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[LAB2:[0-9]+]] = zext i1 %[[BOOL]] to i32
// MCDC-DAG: %[[LAB3:[0-9]+]] = shl i32 %[[LAB2]], 0
// MCDC-DAG: %[[LAB4:[0-9]+]] = or i32 %[[TEMP]], %[[LAB3]]
// MCDC-DAG: %[[TEMP:mcdc.*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[LAB2:[0-9]+]] = add i32 %[[TEMP]], 0
// MCDC-DAG: %[[LAB3:[0-9]+]] = add i32 %[[TEMP]], 0
// MCDC-DAG: %[[LAB4:[0-9]+]] = select i1 %[[BOOL]], i32 %[[LAB2]], i32 %[[LAB3]]
// MCDC-DAG: store i32 %[[LAB4]], ptr %mcdc.addr, align 4

// TERNARY FALSE SHOULD SHIFT ID = 0 FOR CONDITION 'd'.
// MCDC-LABEL: cond.false:
// MCDC: %[[LAB1:[0-9]+]] = load i32, ptr %d.addr, align 4
// MCDC-DAG: %[[BOOL:tobool[0-9]*]] = icmp ne i32 %[[LAB1]], 0
// MCDC-DAG: %[[TEMP:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[LAB2:[0-9]+]] = zext i1 %[[BOOL]] to i32
// MCDC-DAG: %[[LAB3:[0-9]+]] = shl i32 %[[LAB2]], 0
// MCDC-DAG: %[[LAB4:[0-9]+]] = or i32 %[[TEMP]], %[[LAB3]]
// MCDC-DAG: %[[TEMP:mcdc.*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[LAB2:[0-9]+]] = add i32 %[[TEMP]], 0
// MCDC-DAG: %[[LAB3:[0-9]+]] = add i32 %[[TEMP]], 0
// MCDC-DAG: %[[LAB4:[0-9]+]] = select i1 %[[BOOL]], i32 %[[LAB2]], i32 %[[LAB3]]
// MCDC-DAG: store i32 %[[LAB4]], ptr %mcdc.addr, align 4

// SHIFT SECOND CONDITION WITH ID = 2.
// MCDC: %[[LAB1:[0-9]+]] = load i32, ptr %e.addr, align 4
// MCDC-DAG: %[[BOOL:tobool[0-9]*]] = icmp ne i32 %[[LAB1]], 0
// MCDC-DAG: %[[TEMP:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[LAB2:[0-9]+]] = zext i1 %[[BOOL]] to i32
// MCDC-DAG: %[[LAB3:[0-9]+]] = shl i32 %[[LAB2]], 2
// MCDC-DAG: %[[LAB4:[0-9]+]] = or i32 %[[TEMP]], %[[LAB3]]
// MCDC-DAG: %[[TEMP:mcdc.*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[LAB2:[0-9]+]] = add i32 %[[TEMP]], 0
// MCDC-DAG: %[[LAB3:[0-9]+]] = add i32 %[[TEMP]], 1
// MCDC-DAG: %[[LAB4:[0-9]+]] = select i1 %[[BOOL]], i32 %[[LAB2]], i32 %[[LAB3]]
// MCDC-DAG: store i32 %[[LAB4]], ptr %mcdc.addr, align 4

// SHIFT THIRD CONDITION WITH ID = 1.
// MCDC: %[[LAB1:[0-9]+]] = load i32, ptr %f.addr, align 4
// MCDC-DAG: %[[BOOL:tobool[0-9]*]] = icmp ne i32 %[[LAB1]], 0
// MCDC-DAG: %[[TEMP:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[LAB2:[0-9]+]] = zext i1 %[[BOOL]] to i32
// MCDC-DAG: %[[LAB3:[0-9]+]] = shl i32 %[[LAB2]], 1
// MCDC-DAG: %[[LAB4:[0-9]+]] = or i32 %[[TEMP]], %[[LAB3]]
// MCDC-DAG: %[[TEMP:mcdc.*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[LAB2:[0-9]+]] = add i32 %[[TEMP]], 3
// MCDC-DAG: %[[LAB3:[0-9]+]] = add i32 %[[TEMP]], 2
// MCDC-DAG: %[[LAB4:[0-9]+]] = select i1 %[[BOOL]], i32 %[[LAB2]], i32 %[[LAB3]]
// MCDC-DAG: store i32 %[[LAB4]], ptr %mcdc.addr, align 4

// UPDATE FINAL BITMASK WITH RESULT.
// MCDC-DAG: %[[TEMP:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[TEMP0:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC: %[[TEMP:[0-9]+]] = add i32 %[[TEMP0]], 0
// MCDC: %[[LAB1:[0-9]+]] = lshr i32 %[[TEMP]], 3
// MCDC: %[[LAB4:[0-9]+]] = getelementptr inbounds i8, ptr @__profbm_test, i32 %[[LAB1]]
// MCDC: %[[LAB5:[0-9]+]] = and i32 %[[TEMP]], 7
Expand Down
53 changes: 27 additions & 26 deletions clang/test/Profile/c-mcdc-not.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ int test(int a, int b, int c, int d, int e, int f) {
// NOMCDC-NOT: __profbm_test

// MCDC BOOKKEEPING.
// MCDC: @__profbm_test = private global [8 x i8] zeroinitializer
// MCDC: @__profbm_test = private global [2 x i8] zeroinitializer
// MCDC: @__profc_test = private global [9 x i64] zeroinitializer

// ALLOCATE MCDC TEMP AND ZERO IT.
Expand All @@ -21,61 +21,62 @@ int test(int a, int b, int c, int d, int e, int f) {
// MCDC: %[[LAB1:[0-9]+]] = load i32, ptr %a.addr, align 4
// MCDC-DAG: %[[BOOL:tobool[0-9]*]] = icmp ne i32 %[[LAB1]], 0
// MCDC-DAG: %[[LNOT:lnot[0-9]*]] = xor i1 %[[BOOL]]
// MCDC-DAG: %[[TEMP:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[LAB2:[0-9]+]] = zext i1 %[[LNOT]] to i32
// MCDC-DAG: %[[LAB3:[0-9]+]] = shl i32 %[[LAB2]], 0
// MCDC-DAG: %[[LAB4:[0-9]+]] = or i32 %[[TEMP]], %[[LAB3]]
// MCDC-DAG: %[[TEMP:mcdc.*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[LAB2:[0-9]+]] = add i32 %[[TEMP]], 0
// MCDC-DAG: %[[LAB3:[0-9]+]] = add i32 %[[TEMP]], 0
// MCDC-DAG: %[[LAB4:[0-9]+]] = select i1 %[[LNOT]], i32 %[[LAB2]], i32 %[[LAB3]]
// MCDC-DAG: store i32 %[[LAB4]], ptr %mcdc.addr, align 4

// SHIFT SECOND CONDITION WITH ID = 2.
// MCDC: %[[LAB1:[0-9]+]] = load i32, ptr %b.addr, align 4
// MCDC-DAG: %[[BOOL:tobool[0-9]*]] = icmp ne i32 %[[LAB1]], 0
// MCDC-DAG: %[[TEMP:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[LAB2:[0-9]+]] = zext i1 %[[BOOL]] to i32
// MCDC-DAG: %[[LAB3:[0-9]+]] = shl i32 %[[LAB2]], 2
// MCDC-DAG: %[[LAB4:[0-9]+]] = or i32 %[[TEMP]], %[[LAB3]]
// MCDC-DAG: %[[TEMP:mcdc.*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[LAB2:[0-9]+]] = add i32 %[[TEMP]], 14
// MCDC-DAG: %[[LAB3:[0-9]+]] = add i32 %[[TEMP]], 1
// MCDC-DAG: %[[LAB4:[0-9]+]] = select i1 %[[BOOL]], i32 %[[LAB2]], i32 %[[LAB3]]
// MCDC-DAG: store i32 %[[LAB4]], ptr %mcdc.addr, align 4

// SHIFT THIRD CONDITION WITH ID = 1.
// MCDC: %[[LAB1:[0-9]+]] = load i32, ptr %c.addr, align 4
// MCDC-DAG: %[[BOOL:tobool[0-9]*]] = icmp ne i32 %[[LAB1]], 0
// MCDC-DAG: %[[LNOT:lnot[0-9]*]] = xor i1 %[[BOOL]]
// MCDC-DAG: %[[TEMP:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[LAB2:[0-9]+]] = zext i1 %[[LNOT]] to i32
// MCDC-DAG: %[[LAB3:[0-9]+]] = shl i32 %[[LAB2]], 1
// MCDC-DAG: %[[LAB4:[0-9]+]] = or i32 %[[TEMP]], %[[LAB3]]
// MCDC-DAG: %[[TEMP:mcdc.*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[LAB2:[0-9]+]] = add i32 %[[TEMP]], 0
// MCDC-DAG: %[[LAB3:[0-9]+]] = add i32 %[[TEMP]], 0
// MCDC-DAG: %[[LAB4:[0-9]+]] = select i1 %[[LNOT]], i32 %[[LAB2]], i32 %[[LAB3]]
// MCDC-DAG: store i32 %[[LAB4]], ptr %mcdc.addr, align 4

// SHIFT FOURTH CONDITION WITH ID = 4.
// MCDC: %[[LAB1:[0-9]+]] = load i32, ptr %d.addr, align 4
// MCDC-DAG: %[[BOOL:tobool[0-9]*]] = icmp ne i32 %[[LAB1]], 0
// MCDC-DAG: %[[TEMP:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[LAB2:[0-9]+]] = zext i1 %[[BOOL]] to i32
// MCDC-DAG: %[[LAB3:[0-9]+]] = shl i32 %[[LAB2]], 4
// MCDC-DAG: %[[LAB4:[0-9]+]] = or i32 %[[TEMP]], %[[LAB3]]
// MCDC-DAG: %[[TEMP:mcdc.*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[LAB2:[0-9]+]] = add i32 %[[TEMP]], 12
// MCDC-DAG: %[[LAB3:[0-9]+]] = add i32 %[[TEMP]], 2
// MCDC-DAG: %[[LAB4:[0-9]+]] = select i1 %[[BOOL]], i32 %[[LAB2]], i32 %[[LAB3]]
// MCDC-DAG: store i32 %[[LAB4]], ptr %mcdc.addr, align 4

// SHIFT FIFTH CONDITION WITH ID = 3.
// MCDC: %[[LAB1:[0-9]+]] = load i32, ptr %e.addr, align 4
// MCDC-DAG: %[[BOOL:tobool[0-9]*]] = icmp ne i32 %[[LAB1]], 0
// MCDC-DAG: %[[TEMP:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[LAB2:[0-9]+]] = zext i1 %[[BOOL]] to i32
// MCDC-DAG: %[[LAB3:[0-9]+]] = shl i32 %[[LAB2]], 3
// MCDC-DAG: %[[LAB4:[0-9]+]] = or i32 %[[TEMP]], %[[LAB3]]
// MCDC-DAG: %[[TEMP:mcdc.*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[LAB2:[0-9]+]] = add i32 %[[TEMP]], 0
// MCDC-DAG: %[[LAB3:[0-9]+]] = add i32 %[[TEMP]], 0
// MCDC-DAG: %[[LAB4:[0-9]+]] = select i1 %[[BOOL]], i32 %[[LAB2]], i32 %[[LAB3]]
// MCDC-DAG: store i32 %[[LAB4]], ptr %mcdc.addr, align 4

// SHIFT SIXTH CONDITION WITH ID = 5.
// MCDC: %[[LAB1:[0-9]+]] = load i32, ptr %f.addr, align 4
// MCDC-DAG: %[[BOOL:tobool[0-9]*]] = icmp ne i32 %[[LAB1]], 0
// MCDC-DAG: %[[LNOT:lnot[0-9]*]] = xor i1 %[[BOOL]]
// MCDC-DAG: %[[TEMP:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[LAB2:[0-9]+]] = zext i1 %[[LNOT]] to i32
// MCDC-DAG: %[[LAB3:[0-9]+]] = shl i32 %[[LAB2]], 5
// MCDC-DAG: %[[LAB4:[0-9]+]] = or i32 %[[TEMP]], %[[LAB3]]
// MCDC-DAG: %[[TEMP:mcdc.*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[LAB2:[0-9]+]] = add i32 %[[TEMP]], 8
// MCDC-DAG: %[[LAB3:[0-9]+]] = add i32 %[[TEMP]], 4
// MCDC-DAG: %[[LAB4:[0-9]+]] = select i1 %[[LNOT]], i32 %[[LAB2]], i32 %[[LAB3]]
// MCDC-DAG: store i32 %[[LAB4]], ptr %mcdc.addr, align 4

// UPDATE FINAL BITMASK WITH RESULT.
// MCDC-DAG: %[[TEMP:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[TEMP0:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC: %[[TEMP:[0-9]+]] = add i32 %[[TEMP0]], 0
// MCDC: %[[LAB1:[0-9]+]] = lshr i32 %[[TEMP]], 3
// MCDC: %[[LAB4:[0-9]+]] = getelementptr inbounds i8, ptr @__profbm_test, i32 %[[LAB1]]
// MCDC: %[[LAB5:[0-9]+]] = and i32 %[[TEMP]], 7
Expand Down
63 changes: 29 additions & 34 deletions clang/test/Profile/c-mcdc.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,85 +11,80 @@ int test(int a, int b, int c, int d, int e, int f) {
// NOPROFPASS-NOT: __profbm_test

// MCDC BOOKKEEPING.
// MCDC: @__profbm_test = private global [8 x i8] zeroinitializer
// MCDC: @__profbm_test = private global [2 x i8] zeroinitializer
// MCDC: @__profc_test = private global [9 x i64] zeroinitializer

// ALLOCATE MCDC TEMP AND ZERO IT.
// NOPROFPASS-LABEL: @test(
// NOPROFPASS: call void @llvm.instrprof.mcdc.parameters(ptr @__profn_test, i64 [[HASH:[0-9]+]], i32 8)
// NOPROFPASS: call void @llvm.instrprof.mcdc.parameters(ptr @__profn_test, i64 [[HASH:[0-9]+]], i32 15)
// MCDC-LABEL: @test(
// MCDC: %mcdc.addr = alloca i32, align 4
// MCDC: store i32 0, ptr %mcdc.addr, align 4

// SHIFT FIRST CONDITION WITH ID = 0.
// NOPROFPASS: call void @llvm.instrprof.mcdc.condbitmap.update(ptr @__profn_test, i64 [[HASH]], i32 0, ptr %mcdc.addr, i1 %tobool{{[0-9]*}})
// MCDC: %[[LAB1:[0-9]+]] = load i32, ptr %a.addr, align 4
// MCDC-DAG: %[[BOOL:tobool[0-9]*]] = icmp ne i32 %[[LAB1]], 0
// MCDC-DAG: %[[TEMP:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[LAB2:[0-9]+]] = zext i1 %[[BOOL]] to i32
// MCDC-DAG: %[[LAB3:[0-9]+]] = shl i32 %[[LAB2]], 0
// MCDC-DAG: %[[LAB4:[0-9]+]] = or i32 %[[TEMP]], %[[LAB3]]
// MCDC-DAG: %[[TEMP:mcdc.*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[LAB2:[0-9]+]] = add i32 %[[TEMP]], 0
// MCDC-DAG: %[[LAB3:[0-9]+]] = add i32 %[[TEMP]], 0
// MCDC-DAG: %[[LAB4:[0-9]+]] = select i1 %[[BOOL]], i32 %[[LAB2]], i32 %[[LAB3]]
// MCDC-DAG: store i32 %[[LAB4]], ptr %mcdc.addr, align 4

// SHIFT SECOND CONDITION WITH ID = 2.
// NOPROFPASS-LABEL: land.lhs.true:
// NOPROFPASS: call void @llvm.instrprof.mcdc.condbitmap.update(ptr @__profn_test, i64 [[HASH]], i32 2, ptr %mcdc.addr, i1 %tobool{{[0-9]*}})
// MCDC: %[[LAB1:[0-9]+]] = load i32, ptr %b.addr, align 4
// MCDC-DAG: %[[BOOL:tobool[0-9]*]] = icmp ne i32 %[[LAB1]], 0
// MCDC-DAG: %[[TEMP:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[LAB2:[0-9]+]] = zext i1 %[[BOOL]] to i32
// MCDC-DAG: %[[LAB3:[0-9]+]] = shl i32 %[[LAB2]], 2
// MCDC-DAG: %[[LAB4:[0-9]+]] = or i32 %[[TEMP]], %[[LAB3]]
// MCDC-DAG: %[[TEMP:mcdc.*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[LAB2:[0-9]+]] = add i32 %[[TEMP]], 14
// MCDC-DAG: %[[LAB3:[0-9]+]] = add i32 %[[TEMP]], 1
// MCDC-DAG: %[[LAB4:[0-9]+]] = select i1 %[[BOOL]], i32 %[[LAB2]], i32 %[[LAB3]]
// MCDC-DAG: store i32 %[[LAB4]], ptr %mcdc.addr, align 4

// SHIFT THIRD CONDITION WITH ID = 1.
// NOPROFPASS-LABEL: lor.rhs:
// NOPROFPASS: call void @llvm.instrprof.mcdc.condbitmap.update(ptr @__profn_test, i64 [[HASH]], i32 1, ptr %mcdc.addr, i1 %tobool{{[0-9]*}})
// MCDC: %[[LAB1:[0-9]+]] = load i32, ptr %c.addr, align 4
// MCDC-DAG: %[[BOOL:tobool[0-9]*]] = icmp ne i32 %[[LAB1]], 0
// MCDC-DAG: %[[TEMP:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[LAB2:[0-9]+]] = zext i1 %[[BOOL]] to i32
// MCDC-DAG: %[[LAB3:[0-9]+]] = shl i32 %[[LAB2]], 1
// MCDC-DAG: %[[LAB4:[0-9]+]] = or i32 %[[TEMP]], %[[LAB3]]
// MCDC-DAG: %[[TEMP:mcdc.*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[LAB2:[0-9]+]] = add i32 %[[TEMP]], 0
// MCDC-DAG: %[[LAB3:[0-9]+]] = add i32 %[[TEMP]], 0
// MCDC-DAG: %[[LAB4:[0-9]+]] = select i1 %[[BOOL]], i32 %[[LAB2]], i32 %[[LAB3]]
// MCDC-DAG: store i32 %[[LAB4]], ptr %mcdc.addr, align 4

// SHIFT FOURTH CONDITION WITH ID = 4.
// NOPROFPASS-LABEL: land.lhs.true3:
// NOPROFPASS: call void @llvm.instrprof.mcdc.condbitmap.update(ptr @__profn_test, i64 [[HASH]], i32 4, ptr %mcdc.addr, i1 %tobool{{[0-9]*}})
// MCDC: %[[LAB1:[0-9]+]] = load i32, ptr %d.addr, align 4
// MCDC-DAG: %[[BOOL:tobool[0-9]*]] = icmp ne i32 %[[LAB1]], 0
// MCDC-DAG: %[[TEMP:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[LAB2:[0-9]+]] = zext i1 %[[BOOL]] to i32
// MCDC-DAG: %[[LAB3:[0-9]+]] = shl i32 %[[LAB2]], 4
// MCDC-DAG: %[[LAB4:[0-9]+]] = or i32 %[[TEMP]], %[[LAB3]]
// MCDC-DAG: %[[TEMP:mcdc.*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[LAB2:[0-9]+]] = add i32 %[[TEMP]], 12
// MCDC-DAG: %[[LAB3:[0-9]+]] = add i32 %[[TEMP]], 2
// MCDC-DAG: %[[LAB4:[0-9]+]] = select i1 %[[BOOL]], i32 %[[LAB2]], i32 %[[LAB3]]
// MCDC-DAG: store i32 %[[LAB4]], ptr %mcdc.addr, align 4

// SHIFT FIFTH CONDITION WITH ID = 3.
// NOPROFPASS-LABEL: lor.rhs6:
// NOPROFPASS: call void @llvm.instrprof.mcdc.condbitmap.update(ptr @__profn_test, i64 [[HASH]], i32 3, ptr %mcdc.addr, i1 %tobool{{[0-9]*}})
// MCDC: %[[LAB1:[0-9]+]] = load i32, ptr %e.addr, align 4
// MCDC-DAG: %[[BOOL:tobool[0-9]*]] = icmp ne i32 %[[LAB1]], 0
// MCDC-DAG: %[[TEMP:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[LAB2:[0-9]+]] = zext i1 %[[BOOL]] to i32
// MCDC-DAG: %[[LAB3:[0-9]+]] = shl i32 %[[LAB2]], 3
// MCDC-DAG: %[[LAB4:[0-9]+]] = or i32 %[[TEMP]], %[[LAB3]]
// MCDC-DAG: %[[TEMP:mcdc.*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[LAB2:[0-9]+]] = add i32 %[[TEMP]], 0
// MCDC-DAG: %[[LAB3:[0-9]+]] = add i32 %[[TEMP]], 0
// MCDC-DAG: %[[LAB4:[0-9]+]] = select i1 %[[BOOL]], i32 %[[LAB2]], i32 %[[LAB3]]
// MCDC-DAG: store i32 %[[LAB4]], ptr %mcdc.addr, align 4

// SHIFT SIXTH CONDITION WITH ID = 5.
// NOPROFPASS-LABEL: land.rhs:
// NOPROFPASS: call void @llvm.instrprof.mcdc.condbitmap.update(ptr @__profn_test, i64 [[HASH]], i32 5, ptr %mcdc.addr, i1 %tobool{{[0-9]*}})
// MCDC: %[[LAB1:[0-9]+]] = load i32, ptr %f.addr, align 4
// MCDC-DAG: %[[BOOL:tobool[0-9]*]] = icmp ne i32 %[[LAB1]], 0
// MCDC-DAG: %[[TEMP:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[LAB2:[0-9]+]] = zext i1 %[[BOOL]] to i32
// MCDC-DAG: %[[LAB3:[0-9]+]] = shl i32 %[[LAB2]], 5
// MCDC-DAG: %[[LAB4:[0-9]+]] = or i32 %[[TEMP]], %[[LAB3]]
// MCDC-DAG: %[[TEMP:mcdc.*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[LAB2:[0-9]+]] = add i32 %[[TEMP]], 8
// MCDC-DAG: %[[LAB3:[0-9]+]] = add i32 %[[TEMP]], 4
// MCDC-DAG: %[[LAB4:[0-9]+]] = select i1 %[[BOOL]], i32 %[[LAB2]], i32 %[[LAB3]]
// MCDC-DAG: store i32 %[[LAB4]], ptr %mcdc.addr, align 4

// UPDATE FINAL BITMASK WITH RESULT.
// NOPROFPASS-LABEL: lor.end:
// NOPROFPASS: call void @llvm.instrprof.mcdc.tvbitmap.update(ptr @__profn_test, i64 [[HASH]], i32 8, i32 0, ptr %mcdc.addr)
// MCDC-DAG: %[[TEMP:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// NOPROFPASS: call void @llvm.instrprof.mcdc.tvbitmap.update(ptr @__profn_test, i64 [[HASH]], i32 0, i32 0, ptr %mcdc.addr)
// MCDC-DAG: %[[TEMP0:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC: %[[TEMP:[0-9]+]] = add i32 %[[TEMP0]], 0
// MCDC: %[[LAB1:[0-9]+]] = lshr i32 %[[TEMP]], 3
// MCDC: %[[LAB4:[0-9]+]] = getelementptr inbounds i8, ptr @__profbm_test, i32 %[[LAB1]]
// MCDC: %[[LAB5:[0-9]+]] = and i32 %[[TEMP]], 7
Expand Down
4 changes: 2 additions & 2 deletions clang/test/Sema/aarch64-neon-target.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ void undefined(uint32x2_t v2i32, uint32x4_t v4i32, uint16x8_t v8i16, uint8x16_t
vrnd_f16(v4f16); // expected-error {{always_inline function 'vrnd_f16' requires target feature 'fullfp16'}}
vmaxnm_f16(v4f16, v4f16); // expected-error {{always_inline function 'vmaxnm_f16' requires target feature 'fullfp16'}}
vrndi_f16(v4f16); // expected-error {{always_inline function 'vrndi_f16' requires target feature 'fullfp16'}}
// fp16fml depends on fp-armv8
vfmlal_low_f16(v2f32, v4f16, v4f16); // expected-error {{always_inline function 'vfmlal_low_f16' requires target feature 'fp-armv8'}}
// fp16fml
vfmlal_low_f16(v2f32, v4f16, v4f16); // expected-error {{always_inline function 'vfmlal_low_f16' requires target feature 'fp16fml'}}
// i8mm
vmmlaq_s32(v4i32, v8i16, v8i16); // expected-error {{always_inline function 'vmmlaq_s32' requires target feature 'i8mm'}}
vusdot_laneq_s32(v2i32, v8i8, v8i16, 0); // expected-error {{always_inline function 'vusdot_s32' requires target feature 'i8mm'}}
Expand Down
49 changes: 49 additions & 0 deletions clang/test/Sema/debug-93066.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify %s

struct S {
void f() {
++this; // expected-error {{expression is not assignable}}
// expected-note@-1 {{add '*' to dereference it}}
}

void g() const {
++this; // expected-error {{expression is not assignable}}
}
};

void f(int* a, int* const b, const int* const c, __UINTPTR_TYPE__ d) {
// expected-note@-1 {{variable 'b' declared const here}}
// expected-note@-2 {{variable 'c' declared const here}}
(int*)d = 4; // expected-error {{assignment to cast is illegal, lvalue casts are not supported}}
// expected-note@-1 {{add '*' to dereference it}}

++a;
++b; // expected-error {{cannot assign to variable 'b' with const-qualified type 'int *const'}}
// expected-note@-1 {{add '*' to dereference it}}
++c; // expected-error {{cannot assign to variable 'c' with const-qualified type 'const int *const'}}

reinterpret_cast<int*>(42) += 3; // expected-error {{expression is not assignable}}
// expected-note@-1 {{add '*' to dereference it}}

const int x = 42;
(const_cast<int*>(&x)) += 3; // expected-error {{expression is not assignable}}
// expected-note@-1 {{add '*' to dereference it}}
}

template <typename T>
void f(T& t) {
// expected-note@* 2 {{variable 't' declared const here}}
++t;
// expected-error@-1 {{cannot assign to variable 't' with const-qualified type 'int *const &'}}
// expected-error@-2 {{cannot assign to variable 't' with const-qualified type 'const int *const &'}}
// expected-note@-3 {{add '*' to dereference it}}
}

void g() {
int* a;
int* const b = a;
const int* const c = a;
f(a);
f(b); // expected-note {{in instantiation of function template specialization 'f<int *const>' requested here}}
f(c); // expected-note {{in instantiation of function template specialization 'f<const int *const>' requested here}}
}
2 changes: 2 additions & 0 deletions clang/test/Sema/exprs.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,10 @@ void test4(void) {

void test5(int *X, float *P) {
(float*)X = P; // expected-error {{assignment to cast is illegal, lvalue casts are not supported}}
// expected-note@-1 {{add '*' to dereference it}}
#define FOO ((float*) X)
FOO = P; // expected-error {{assignment to cast is illegal, lvalue casts are not supported}}
// expected-note@-1 {{add '*' to dereference it}}
}

void test6(void) {
Expand Down
1 change: 1 addition & 0 deletions clang/test/Sema/va_arg_x86_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@

int a(void) {
__builtin_va_arg((char*)0, int); // expected-error {{expression is not assignable}}
// expected-note@-1 {{add '*' to dereference it}}
__builtin_va_arg((void*){0}, int); // expected-error {{first argument to 'va_arg' is of type 'void *'}}
}
1 change: 1 addition & 0 deletions clang/test/SemaCXX/cxx0x-initializer-references.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -fexperimental-new-constant-interpreter

struct one { char c; };
struct two { char c[2]; };
Expand Down
13 changes: 13 additions & 0 deletions clang/test/SemaObjCXX/sel-address.mm
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,20 @@ void h() {
SEL s = @selector(dealloc);
SEL* ps = &s;

/*
FIXME: https://github.com/llvm/llvm-project/pull/94159
TLDR; This is about inserting '*' to deref.
This would assign the value of s to the SEL object pointed to by
@selector(dealloc). However, in Objective-C, selectors are not pointers,
they are special compile-time constructs representing method names, and
they are immutable, so you cannot assign values to them.
Therefore, this syntax is not valid for selectors in Objective-C.
*/
@selector(dealloc) = s; // expected-error {{expression is not assignable}}
// expected-note@-1 {{add '*' to dereference it}}

SEL* ps2 = &@selector(dealloc);

Expand Down
143 changes: 141 additions & 2 deletions clang/test/SemaTemplate/deduction-guide.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ using AFoo = Foo<G<U>>;
// CHECK-NEXT: | | `-IntegerLiteral {{.*}}
// CHECK-NEXT: | `-TypeTraitExpr {{.*}} 'bool' __is_deducible
// CHECK-NEXT: | |-DeducedTemplateSpecializationType {{.*}} 'AFoo' dependent
// CHECK-NEXT: | | `-name: 'AFoo'
// CHECK-NEXT: | | `-name: 'AFoo'
// CHECK-NEXT: | | `-TypeAliasTemplateDecl {{.+}} AFoo
// CHECK-NEXT: | `-TemplateSpecializationType {{.*}} 'Foo<G<type-parameter-0-0>>' dependent
// CHECK: |-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for AFoo> 'auto (G<type-parameter-0-0>) -> Foo<G<type-parameter-0-0>>'
Expand Down Expand Up @@ -330,8 +330,147 @@ namespace TTP {
// CHECK-NEXT: | `-CXXRecord {{.+}} 'B'{{$}}
// CHECK-NEXT: `-ElaboratedType {{.+}} 'template-parameter-0-1<T>' sugar dependent{{$}}
// CHECK-NEXT: `-TemplateSpecializationType {{.+}} 'template-parameter-0-1<T>' dependent{{$}}
// CHECK-NEXT: |-name: 'template-parameter-0-1' qualified
// CHECK-NEXT: |-name: 'template-parameter-0-1' qualified
// CHECK-NEXT: | `-TemplateTemplateParmDecl {{.+}} depth 0 index 1
// CHECK-NEXT: `-TemplateArgument type 'T':'type-parameter-0-0'{{$}}
// CHECK-NEXT: `-TemplateTypeParmType {{.+}} 'T' dependent depth 0 index 0{{$}}
// CHECK-NEXT: `-TemplateTypeParm {{.+}} 'T'{{$}}

namespace GH64625 {

template <class T> struct X {
T t[2];
};

X x = {{1, 2}};

// CHECK-LABEL: Dumping GH64625::<deduction guide for X>:
// CHECK-NEXT: FunctionTemplateDecl {{.+}} <{{.+}}:[[#@LINE - 7]]:1, col:27> col:27 implicit <deduction guide for X>
// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} <col:11, col:17> col:17 referenced class depth 0 index 0 T
// CHECK: |-CXXDeductionGuideDecl {{.+}} <col:27> col:27 implicit <deduction guide for X> 'auto (T (&&)[2]) -> X<T>' aggregate
// CHECK-NEXT: | `-ParmVarDecl {{.+}} <col:27> col:27 'T (&&)[2]'
// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} <col:27> col:27 implicit used <deduction guide for X> 'auto (int (&&)[2]) -> GH64625::X<int>' implicit_instantiation aggregate
// CHECK-NEXT: |-TemplateArgument type 'int'
// CHECK-NEXT: | `-BuiltinType {{.+}} 'int'
// CHECK-NEXT: `-ParmVarDecl {{.+}} <col:27> col:27 'int (&&)[2]'
// CHECK-NEXT: FunctionProtoType {{.+}} 'auto (T (&&)[2]) -> X<T>' dependent trailing_return
// CHECK-NEXT: |-InjectedClassNameType {{.+}} 'X<T>' dependent
// CHECK-NEXT: | `-CXXRecord {{.+}} 'X'
// CHECK-NEXT: `-RValueReferenceType {{.+}} 'T (&&)[2]' dependent
// CHECK-NEXT: `-ConstantArrayType {{.+}} 'T[2]' dependent 2
// CHECK-NEXT: `-TemplateTypeParmType {{.+}} 'T' dependent depth 0 index 0
// CHECK-NEXT: `-TemplateTypeParm {{.+}} 'T'

template <class T, class U> struct TwoArrays {
T t[2];
U u[3];
};

TwoArrays ta = {{1, 2}, {3, 4, 5}};
// CHECK-LABEL: Dumping GH64625::<deduction guide for TwoArrays>:
// CHECK-NEXT: FunctionTemplateDecl {{.+}} <{{.+}}:[[#@LINE - 7]]:1, col:36> col:36 implicit <deduction guide for TwoArrays>
// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} <col:11, col:17> col:17 referenced class depth 0 index 0 T
// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} <col:20, col:26> col:26 referenced class depth 0 index 1 U
// CHECK: |-CXXDeductionGuideDecl {{.+}} <col:36> col:36 implicit <deduction guide for TwoArrays> 'auto (T (&&)[2], U (&&)[3]) -> TwoArrays<T, U>' aggregate
// CHECK-NEXT: | |-ParmVarDecl {{.+}} <col:36> col:36 'T (&&)[2]'
// CHECK-NEXT: | `-ParmVarDecl {{.+}} <col:36> col:36 'U (&&)[3]'
// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} <col:36> col:36 implicit used <deduction guide for TwoArrays> 'auto (int (&&)[2], int (&&)[3]) -> GH64625::TwoArrays<int, int>' implicit_instantiation aggregate
// CHECK-NEXT: |-TemplateArgument type 'int'
// CHECK-NEXT: | `-BuiltinType {{.+}} 'int'
// CHECK-NEXT: |-TemplateArgument type 'int'
// CHECK-NEXT: | `-BuiltinType {{.+}} 'int'
// CHECK-NEXT: |-ParmVarDecl {{.+}} <col:36> col:36 'int (&&)[2]'
// CHECK-NEXT: `-ParmVarDecl {{.+}} <col:36> col:36 'int (&&)[3]'
// CHECK-NEXT: FunctionProtoType {{.+}} 'auto (T (&&)[2], U (&&)[3]) -> TwoArrays<T, U>' dependent trailing_return
// CHECK-NEXT: |-InjectedClassNameType {{.+}} 'TwoArrays<T, U>' dependent
// CHECK-NEXT: | `-CXXRecord {{.+}} 'TwoArrays'
// CHECK-NEXT: |-RValueReferenceType {{.+}} 'T (&&)[2]' dependent
// CHECK-NEXT: | `-ConstantArrayType {{.+}} 'T[2]' dependent 2
// CHECK-NEXT: | `-TemplateTypeParmType {{.+}} 'T' dependent depth 0 index 0
// CHECK-NEXT: | `-TemplateTypeParm {{.+}} 'T'
// CHECK-NEXT: `-RValueReferenceType {{.+}} 'U (&&)[3]' dependent
// CHECK-NEXT: `-ConstantArrayType {{.+}} 'U[3]' dependent 3
// CHECK-NEXT: `-TemplateTypeParmType {{.+}} 'U' dependent depth 0 index 1
// CHECK-NEXT: `-TemplateTypeParm {{.+}} 'U'

TwoArrays tb = {1, 2, {3, 4, 5}};
// CHECK: |-CXXDeductionGuideDecl {{.+}} <col:36> col:36 implicit <deduction guide for TwoArrays> 'auto (T, T, U (&&)[3]) -> TwoArrays<T, U>' aggregate
// CHECK-NEXT: | |-ParmVarDecl {{.+}} <col:36> col:36 'T'
// CHECK-NEXT: | |-ParmVarDecl {{.+}} <col:36> col:36 'T'
// CHECK-NEXT: | `-ParmVarDecl {{.+}} <col:36> col:36 'U (&&)[3]'
// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} <col:36> col:36 implicit used <deduction guide for TwoArrays> 'auto (int, int, int (&&)[3]) -> GH64625::TwoArrays<int, int>' implicit_instantiation aggregate
// CHECK-NEXT: |-TemplateArgument type 'int'
// CHECK-NEXT: | `-BuiltinType {{.+}} 'int'
// CHECK-NEXT: |-TemplateArgument type 'int'
// CHECK-NEXT: | `-BuiltinType {{.+}} 'int'
// CHECK-NEXT: |-ParmVarDecl {{.+}} <col:36> col:36 'int'
// CHECK-NEXT: |-ParmVarDecl {{.+}} <col:36> col:36 'int'
// CHECK-NEXT: `-ParmVarDecl {{.+}} <col:36> col:36 'int (&&)[3]'
// CHECK-NEXT: FunctionProtoType {{.+}} 'auto (T, T, U (&&)[3]) -> TwoArrays<T, U>' dependent trailing_return
// CHECK-NEXT: |-InjectedClassNameType {{.+}} 'TwoArrays<T, U>' dependent
// CHECK-NEXT: | `-CXXRecord {{.+}} 'TwoArrays'
// CHECK-NEXT: |-TemplateTypeParmType {{.+}} 'T' dependent depth 0 index 0
// CHECK-NEXT: | `-TemplateTypeParm {{.+}} 'T'
// CHECK-NEXT: |-TemplateTypeParmType {{.+}} 'T' dependent depth 0 index 0
// CHECK-NEXT: | `-TemplateTypeParm {{.+}} 'T'
// CHECK-NEXT: `-RValueReferenceType {{.+}} 'U (&&)[3]' dependent
// CHECK-NEXT: `-ConstantArrayType {{.+}} 'U[3]' dependent 3
// CHECK-NEXT: `-TemplateTypeParmType {{.+}} 'U' dependent depth 0 index 1
// CHECK-NEXT: `-TemplateTypeParm {{.+}} 'U'

TwoArrays tc = {{1, 2}, 3, 4, 5};
// CHECK: |-CXXDeductionGuideDecl {{.+}} <col:36> col:36 implicit <deduction guide for TwoArrays> 'auto (T (&&)[2], U, U, U) -> TwoArrays<T, U>' aggregate
// CHECK-NEXT: | |-ParmVarDecl {{.+}} <col:36> col:36 'T (&&)[2]'
// CHECK-NEXT: | |-ParmVarDecl {{.+}} <col:36> col:36 'U'
// CHECK-NEXT: | |-ParmVarDecl {{.+}} <col:36> col:36 'U'
// CHECK-NEXT: | `-ParmVarDecl {{.+}} <col:36> col:36 'U'
// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} <col:36> col:36 implicit used <deduction guide for TwoArrays> 'auto (int (&&)[2], int, int, int) -> GH64625::TwoArrays<int, int>' implicit_instantiation aggregate
// CHECK-NEXT: |-TemplateArgument type 'int'
// CHECK-NEXT: | `-BuiltinType {{.+}} 'int'
// CHECK-NEXT: |-TemplateArgument type 'int'
// CHECK-NEXT: | `-BuiltinType {{.+}} 'int'
// CHECK-NEXT: |-ParmVarDecl {{.+}} <col:36> col:36 'int (&&)[2]'
// CHECK-NEXT: |-ParmVarDecl {{.+}} <col:36> col:36 'int'
// CHECK-NEXT: |-ParmVarDecl {{.+}} <col:36> col:36 'int'
// CHECK-NEXT: `-ParmVarDecl {{.+}} <col:36> col:36 'int'
// CHECK-NEXT: FunctionProtoType {{.+}} 'auto (T (&&)[2], U, U, U) -> TwoArrays<T, U>' dependent trailing_return
// CHECK-NEXT: |-InjectedClassNameType {{.+}} 'TwoArrays<T, U>' dependent
// CHECK-NEXT: | `-CXXRecord {{.+}} 'TwoArrays'
// CHECK-NEXT: |-RValueReferenceType {{.+}} 'T (&&)[2]' dependent
// CHECK-NEXT: | `-ConstantArrayType {{.+}} 'T[2]' dependent 2
// CHECK-NEXT: | `-TemplateTypeParmType {{.+}} 'T' dependent depth 0 index 0
// CHECK-NEXT: | `-TemplateTypeParm {{.+}} 'T'
// CHECK-NEXT: |-TemplateTypeParmType {{.+}} 'U' dependent depth 0 index 1
// CHECK-NEXT: | `-TemplateTypeParm {{.+}} 'U'
// CHECK-NEXT: |-TemplateTypeParmType {{.+}} 'U' dependent depth 0 index 1
// CHECK-NEXT: | `-TemplateTypeParm {{.+}} 'U'
// CHECK-NEXT: `-TemplateTypeParmType {{.+}} 'U' dependent depth 0 index 1
// CHECK-NEXT: `-TemplateTypeParm {{.+}} 'U'

} // namespace GH64625

namespace GH83368 {

template <int N> struct A {
int f1[N];
};

A a{.f1 = {1}};

// CHECK-LABEL: Dumping GH83368::<deduction guide for A>:
// CHECK-NEXT: FunctionTemplateDecl 0x{{.+}} <{{.+}}:[[#@LINE - 7]]:1, col:25> col:25 implicit <deduction guide for A>
// CHECK-NEXT: |-NonTypeTemplateParmDecl {{.+}} <col:11, col:15> col:15 referenced 'int' depth 0 index 0 N
// CHECK: |-CXXDeductionGuideDecl {{.+}} <col:25> col:25 implicit <deduction guide for A> 'auto (int (&&)[N]) -> A<N>' aggregate
// CHECK-NEXT: | `-ParmVarDecl {{.+}} <col:25> col:25 'int (&&)[N]'
// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} <col:25> col:25 implicit used <deduction guide for A> 'auto (int (&&)[1]) -> GH83368::A<1>' implicit_instantiation aggregate
// CHECK-NEXT: |-TemplateArgument integral '1'
// CHECK-NEXT: `-ParmVarDecl {{.+}} <col:25> col:25 'int (&&)[1]'
// CHECK-NEXT: FunctionProtoType {{.+}} 'auto (int (&&)[N]) -> A<N>' dependent trailing_return
// CHECK-NEXT: |-InjectedClassNameType {{.+}} 'A<N>' dependent
// CHECK-NEXT: | `-CXXRecord {{.+}} 'A'
// CHECK-NEXT: `-RValueReferenceType {{.+}} 'int (&&)[N]' dependent
// CHECK-NEXT: `-DependentSizedArrayType {{.+}} 'int[N]' dependent
// CHECK-NEXT: |-BuiltinType {{.+}} 'int'
// CHECK-NEXT: `-DeclRefExpr {{.+}} <col:10> 'int' NonTypeTemplateParm {{.+}} 'N' 'int'

} // namespace GH83368
1 change: 1 addition & 0 deletions clang/unittests/AST/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ add_clang_unittest(ASTTests
EvaluateAsRValueTest.cpp
ExternalASTSourceTest.cpp
NamedDeclPrinterTest.cpp
ProfilingTest.cpp
RandstructTest.cpp
RecursiveASTVisitorTest.cpp
SizelessTypesTest.cpp
Expand Down
75 changes: 75 additions & 0 deletions clang/unittests/AST/ProfilingTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
//===- unittests/AST/ProfilingTest.cpp --- Tests for Profiling ------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Tooling/Tooling.h"
#include "gtest/gtest.h"
#include <utility>

namespace clang {
namespace {
using namespace ast_matchers;

static auto getClassTemplateRedecls() {
std::string Code = R"cpp(
template <class> struct A;
template <class> struct A;
template <class> struct A;
)cpp";
auto AST = tooling::buildASTFromCode(Code);
ASTContext &Ctx = AST->getASTContext();

auto MatchResults = match(classTemplateDecl().bind("id"), Ctx);
SmallVector<ClassTemplateDecl *, 3> Res;
for (BoundNodes &N : MatchResults) {
if (auto *CTD = const_cast<ClassTemplateDecl *>(
N.getNodeAs<ClassTemplateDecl>("id")))
Res.push_back(CTD);
}
assert(Res.size() == 3);
#ifndef NDEBUG
for (auto &&I : Res)
assert(I->getCanonicalDecl() == Res[0]);
#endif
return std::make_tuple(std::move(AST), Res[1], Res[2]);
}

template <class T> static void testTypeNode(const T *T1, const T *T2) {
{
llvm::FoldingSetNodeID ID1, ID2;
T1->Profile(ID1);
T2->Profile(ID2);
ASSERT_NE(ID1, ID2);
}
auto *CT1 = cast<T>(T1->getCanonicalTypeInternal());
auto *CT2 = cast<T>(T2->getCanonicalTypeInternal());
{
llvm::FoldingSetNodeID ID1, ID2;
CT1->Profile(ID1);
CT2->Profile(ID2);
ASSERT_EQ(ID1, ID2);
}
}

TEST(Profiling, DeducedTemplateSpecializationType_Name) {
auto [AST, CTD1, CTD2] = getClassTemplateRedecls();
ASTContext &Ctx = AST->getASTContext();

auto *T1 = cast<DeducedTemplateSpecializationType>(
Ctx.getDeducedTemplateSpecializationType(TemplateName(CTD1), QualType(),
false));
auto *T2 = cast<DeducedTemplateSpecializationType>(
Ctx.getDeducedTemplateSpecializationType(TemplateName(CTD2), QualType(),
false));
testTypeNode(T1, T2);
}

} // namespace
} // namespace clang
6 changes: 6 additions & 0 deletions clang/www/cxx_dr_status.html
Original file line number Diff line number Diff line change
Expand Up @@ -17198,6 +17198,12 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td>open</td>
<td>Clarify implicit conversion sequence from <I>cv</I> <TT>T</TT> to <TT>T</TT></td>
<td align="center">Not resolved</td>
</tr>
<tr class="open" id="2899">
<td><a href="https://cplusplus.github.io/CWG/issues/2899.html">2899</a></td>
<td>open</td>
<td>Bad value representations should cause undefined behavior</td>
<td align="center">Not resolved</td>
</tr></table>

</div>
Expand Down
8 changes: 8 additions & 0 deletions compiler-rt/lib/builtins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,14 @@ if(NOT FUCHSIA AND NOT COMPILER_RT_BAREMETAL_BUILD)
)
endif()

option(COMPILER_RT_LIBATOMIC_USE_PTHREAD
"Whether libatomic should use pthreads if available."
Off)

if(COMPILER_RT_LIBATOMIC_USE_PTHREAD)
add_compile_definitions(_LIBATOMIC_USE_PTHREAD)
endif()

if(COMPILER_RT_HAS_ATOMIC_KEYWORD AND NOT COMPILER_RT_EXCLUDE_ATOMIC_BUILTIN)
set(GENERIC_SOURCES
${GENERIC_SOURCES}
Expand Down
12 changes: 8 additions & 4 deletions compiler-rt/lib/builtins/aarch64/sme-abi-vg.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "../cpu_model/aarch64.h"

struct FEATURES {
long long features;
unsigned long long features;
};

extern struct FEATURES __aarch64_cpu_features;
Expand All @@ -23,14 +23,18 @@ extern bool __aarch64_has_sme_and_tpidr2_el0;
#pragma GCC diagnostic ignored "-Wprio-ctor-dtor"
#endif
__attribute__((constructor(90))) static void get_aarch64_cpu_features(void) {
if (!__aarch64_cpu_features.features)
__init_cpu_features();
if (__atomic_load_n(&__aarch64_cpu_features.features, __ATOMIC_RELAXED))
return;

__init_cpu_features();
}

__attribute__((target("sve"))) long
__arm_get_current_vg(void) __arm_streaming_compatible {
struct SME_STATE State = __arm_sme_state();
bool HasSVE = __aarch64_cpu_features.features & (1ULL << FEAT_SVE);
unsigned long long features =
__atomic_load_n(&__aarch64_cpu_features.features, __ATOMIC_RELAXED);
bool HasSVE = features & (1ULL << FEAT_SVE);

if (!HasSVE && !__aarch64_has_sme_and_tpidr2_el0)
return 0;
Expand Down
14 changes: 12 additions & 2 deletions compiler-rt/lib/builtins/atomic.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
//
// 1) This code must work with C programs that do not link to anything
// (including pthreads) and so it should not depend on any pthread
// functions.
// functions. If the user wishes to opt into using pthreads, they may do so.
// 2) Atomic operations, rather than explicit mutexes, are most commonly used
// on code where contended operations are rate.
//
Expand Down Expand Up @@ -56,7 +56,17 @@ static const long SPINLOCK_MASK = SPINLOCK_COUNT - 1;
// defined. Each platform should define the Lock type, and corresponding
// lock() and unlock() functions.
////////////////////////////////////////////////////////////////////////////////
#if defined(__FreeBSD__) || defined(__DragonFly__)
#if defined(_LIBATOMIC_USE_PTHREAD)
#include <pthread.h>
typedef pthread_mutex_t Lock;
/// Unlock a lock. This is a release operation.
__inline static void unlock(Lock *l) { pthread_mutex_unlock(l); }
/// Locks a lock.
__inline static void lock(Lock *l) { pthread_mutex_lock(l); }
/// locks for atomic operations
static Lock locks[SPINLOCK_COUNT];

#elif defined(__FreeBSD__) || defined(__DragonFly__)
#include <errno.h>
// clang-format off
#include <sys/types.h>
Expand Down
4 changes: 2 additions & 2 deletions compiler-rt/lib/builtins/cpu_model/aarch64/fmv/android.inc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
void __init_cpu_features_resolver(unsigned long hwcap,
const __ifunc_arg_t *arg) {
if (__aarch64_cpu_features.features)
if (__atomic_load_n(&__aarch64_cpu_features.features, __ATOMIC_RELAXED))
return;

// ifunc resolvers don't have hwcaps in arguments on Android API lower
Expand All @@ -17,7 +17,7 @@ void __init_cpu_features_resolver(unsigned long hwcap,

void CONSTRUCTOR_ATTRIBUTE __init_cpu_features(void) {
// CPU features already initialized.
if (__aarch64_cpu_features.features)
if (__atomic_load_n(&__aarch64_cpu_features.features, __ATOMIC_RELAXED))
return;

// Don't set any CPU features,
Expand Down
4 changes: 2 additions & 2 deletions compiler-rt/lib/builtins/cpu_model/aarch64/fmv/freebsd.inc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
void __init_cpu_features_resolver(unsigned long hwcap,
const __ifunc_arg_t *arg) {
if (__aarch64_cpu_features.features)
if (__atomic_load_n(&__aarch64_cpu_features.features, __ATOMIC_RELAXED))
return;

__init_cpu_features_constructor(hwcap, arg);
Expand All @@ -10,7 +10,7 @@ void CONSTRUCTOR_ATTRIBUTE __init_cpu_features(void) {
unsigned long hwcap = 0;
unsigned long hwcap2 = 0;
// CPU features already initialized.
if (__aarch64_cpu_features.features)
if (__atomic_load_n(&__aarch64_cpu_features.features, __ATOMIC_RELAXED))
return;

int res = 0;
Expand Down
8 changes: 5 additions & 3 deletions compiler-rt/lib/builtins/cpu_model/aarch64/fmv/fuchsia.inc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#include <zircon/syscalls.h>

void __init_cpu_features_resolver() {
if (__aarch64_cpu_features.features)
if (__atomic_load_n(&__aarch64_cpu_features.features, __ATOMIC_RELAXED))
return;

// This ensures the vDSO is a direct link-time dependency of anything that
Expand All @@ -13,8 +13,8 @@ void __init_cpu_features_resolver() {
if (status != ZX_OK)
return;

#define setCPUFeature(cpu_feature) \
__aarch64_cpu_features.features |= 1ULL << cpu_feature
unsigned long long feat = 0;
#define setCPUFeature(cpu_feature) feat |= 1ULL << cpu_feature

if (features & ZX_ARM64_FEATURE_ISA_FP)
setCPUFeature(FEAT_FP);
Expand Down Expand Up @@ -48,4 +48,6 @@ void __init_cpu_features_resolver() {
setCPUFeature(FEAT_SVE);

setCPUFeature(FEAT_INIT);

__atomic_store_n(&__aarch64_cpu_features.features, feat, __ATOMIC_RELAXED);
}
135 changes: 43 additions & 92 deletions compiler-rt/lib/builtins/cpu_model/aarch64/fmv/mrs.inc
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@
#define HAVE_SYS_AUXV_H
#endif



static void __init_cpu_features_constructor(unsigned long hwcap,
const __ifunc_arg_t *arg) {
#define setCPUFeature(F) __aarch64_cpu_features.features |= 1ULL << F
unsigned long long feat = 0;
#define setCPUFeature(F) feat |= 1ULL << F
#define getCPUFeature(id, ftr) __asm__("mrs %0, " #id : "=r"(ftr))
#define extractBits(val, start, number) \
(val & ((1ULL << number) - 1ULL) << start) >> start
Expand All @@ -20,26 +19,20 @@ static void __init_cpu_features_constructor(unsigned long hwcap,
setCPUFeature(FEAT_PMULL);
if (hwcap & HWCAP_FLAGM)
setCPUFeature(FEAT_FLAGM);
if (hwcap2 & HWCAP2_FLAGM2) {
setCPUFeature(FEAT_FLAGM);
if (hwcap2 & HWCAP2_FLAGM2)
setCPUFeature(FEAT_FLAGM2);
}
if (hwcap & HWCAP_SM3 && hwcap & HWCAP_SM4)
if (hwcap & HWCAP_SM4)
setCPUFeature(FEAT_SM4);
if (hwcap & HWCAP_ASIMDDP)
setCPUFeature(FEAT_DOTPROD);
if (hwcap & HWCAP_ASIMDFHM)
setCPUFeature(FEAT_FP16FML);
if (hwcap & HWCAP_FPHP) {
if (hwcap & HWCAP_FPHP)
setCPUFeature(FEAT_FP16);
setCPUFeature(FEAT_FP);
}
if (hwcap & HWCAP_DIT)
setCPUFeature(FEAT_DIT);
if (hwcap & HWCAP_ASIMDRDM)
setCPUFeature(FEAT_RDM);
if (hwcap & HWCAP_ILRCPC)
setCPUFeature(FEAT_RCPC2);
if (hwcap & HWCAP_AES)
setCPUFeature(FEAT_AES);
if (hwcap & HWCAP_SHA1)
Expand All @@ -52,23 +45,20 @@ static void __init_cpu_features_constructor(unsigned long hwcap,
setCPUFeature(FEAT_FCMA);
if (hwcap & HWCAP_SB)
setCPUFeature(FEAT_SB);
if (hwcap & HWCAP_SSBS)
if (hwcap & HWCAP_SSBS) {
setCPUFeature(FEAT_SSBS);
setCPUFeature(FEAT_SSBS2);
}
if (hwcap2 & HWCAP2_MTE) {
setCPUFeature(FEAT_MEMTAG);
setCPUFeature(FEAT_MEMTAG2);
}
if (hwcap2 & HWCAP2_MTE3) {
setCPUFeature(FEAT_MEMTAG);
setCPUFeature(FEAT_MEMTAG2);
if (hwcap2 & HWCAP2_MTE3)
setCPUFeature(FEAT_MEMTAG3);
}
if (hwcap2 & HWCAP2_SVEAES)
setCPUFeature(FEAT_SVE_AES);
if (hwcap2 & HWCAP2_SVEPMULL) {
setCPUFeature(FEAT_SVE_AES);
if (hwcap2 & HWCAP2_SVEPMULL)
setCPUFeature(FEAT_SVE_PMULL128);
}
if (hwcap2 & HWCAP2_SVEBITPERM)
setCPUFeature(FEAT_SVE_BITPERM);
if (hwcap2 & HWCAP2_SVESHA3)
Expand Down Expand Up @@ -105,6 +95,8 @@ static void __init_cpu_features_constructor(unsigned long hwcap,
setCPUFeature(FEAT_WFXT);
if (hwcap2 & HWCAP2_SME)
setCPUFeature(FEAT_SME);
if (hwcap2 & HWCAP2_SME2)
setCPUFeature(FEAT_SME2);
if (hwcap2 & HWCAP2_SME_I16I64)
setCPUFeature(FEAT_SME_I64);
if (hwcap2 & HWCAP2_SME_F64F64)
Expand All @@ -113,86 +105,45 @@ static void __init_cpu_features_constructor(unsigned long hwcap,
setCPUFeature(FEAT_MOPS);
if (hwcap & HWCAP_CPUID) {
unsigned long ftr;
getCPUFeature(ID_AA64PFR1_EL1, ftr);
// ID_AA64PFR1_EL1.MTE >= 0b0001
if (extractBits(ftr, 8, 4) >= 0x1)
setCPUFeature(FEAT_MEMTAG);
// ID_AA64PFR1_EL1.SSBS == 0b0001
if (extractBits(ftr, 4, 4) == 0x1)
setCPUFeature(FEAT_SSBS);
// ID_AA64PFR1_EL1.SME == 0b0010
if (extractBits(ftr, 24, 4) == 0x2)
setCPUFeature(FEAT_SME2);
getCPUFeature(ID_AA64PFR0_EL1, ftr);
// ID_AA64PFR0_EL1.FP != 0b1111
if (extractBits(ftr, 16, 4) != 0xF) {
setCPUFeature(FEAT_FP);
// ID_AA64PFR0_EL1.AdvSIMD has the same value as ID_AA64PFR0_EL1.FP
setCPUFeature(FEAT_SIMD);
}
// ID_AA64PFR0_EL1.SVE != 0b0000
if (extractBits(ftr, 32, 4) != 0x0) {
// get ID_AA64ZFR0_EL1, that name supported
// if sve enabled only
getCPUFeature(S3_0_C0_C4_4, ftr);
// ID_AA64ZFR0_EL1.SVEver == 0b0000
if (extractBits(ftr, 0, 4) == 0x0)
setCPUFeature(FEAT_SVE);
// ID_AA64ZFR0_EL1.SVEver == 0b0001
if (extractBits(ftr, 0, 4) == 0x1)
setCPUFeature(FEAT_SVE2);
// ID_AA64ZFR0_EL1.BF16 != 0b0000
if (extractBits(ftr, 20, 4) != 0x0)
setCPUFeature(FEAT_SVE_BF16);
}
getCPUFeature(ID_AA64ISAR0_EL1, ftr);
// ID_AA64ISAR0_EL1.SHA3 != 0b0000
if (extractBits(ftr, 32, 4) != 0x0)
setCPUFeature(FEAT_SHA3);

getCPUFeature(ID_AA64ISAR1_EL1, ftr);
// ID_AA64ISAR1_EL1.DPB >= 0b0001
if (extractBits(ftr, 0, 4) >= 0x1)
setCPUFeature(FEAT_DPB);
// ID_AA64ISAR1_EL1.LRCPC != 0b0000
if (extractBits(ftr, 20, 4) != 0x0)
setCPUFeature(FEAT_RCPC);
// ID_AA64ISAR1_EL1.LRCPC == 0b0011
if (extractBits(ftr, 20, 4) == 0x3)
setCPUFeature(FEAT_RCPC3);
// ID_AA64ISAR1_EL1.SPECRES == 0b0001
if (extractBits(ftr, 40, 4) == 0x2)
/* ID_AA64ISAR1_EL1.SPECRES >= 0b0001 */
if (extractBits(ftr, 40, 4) >= 0x1)
setCPUFeature(FEAT_PREDRES);
// ID_AA64ISAR1_EL1.BF16 != 0b0000
if (extractBits(ftr, 44, 4) != 0x0)
setCPUFeature(FEAT_BF16);
// ID_AA64ISAR1_EL1.LS64 >= 0b0001
/* ID_AA64ISAR1_EL1.LS64 >= 0b0001 */
if (extractBits(ftr, 60, 4) >= 0x1)
setCPUFeature(FEAT_LS64);
// ID_AA64ISAR1_EL1.LS64 >= 0b0010
/* ID_AA64ISAR1_EL1.LS64 >= 0b0010 */
if (extractBits(ftr, 60, 4) >= 0x2)
setCPUFeature(FEAT_LS64_V);
// ID_AA64ISAR1_EL1.LS64 >= 0b0011
/* ID_AA64ISAR1_EL1.LS64 >= 0b0011 */
if (extractBits(ftr, 60, 4) >= 0x3)
setCPUFeature(FEAT_LS64_ACCDATA);
} else {
// Set some features in case of no CPUID support
if (hwcap & (HWCAP_FP | HWCAP_FPHP)) {
setCPUFeature(FEAT_FP);
// FP and AdvSIMD fields have the same value
setCPUFeature(FEAT_SIMD);
}
if (hwcap & HWCAP_DCPOP || hwcap2 & HWCAP2_DCPODP)
setCPUFeature(FEAT_DPB);
if (hwcap & HWCAP_LRCPC || hwcap & HWCAP_ILRCPC)
setCPUFeature(FEAT_RCPC);
if (hwcap2 & HWCAP2_BF16 || hwcap2 & HWCAP2_EBF16)
setCPUFeature(FEAT_BF16);
if (hwcap2 & HWCAP2_SVEBF16)
setCPUFeature(FEAT_SVE_BF16);
if (hwcap2 & HWCAP2_SVE2 && hwcap & HWCAP_SVE)
setCPUFeature(FEAT_SVE2);
if (hwcap & HWCAP_SHA3)
setCPUFeature(FEAT_SHA3);
}
if (hwcap & HWCAP_FP) {
setCPUFeature(FEAT_FP);
// FP and AdvSIMD fields have the same value
setCPUFeature(FEAT_SIMD);
}
if (hwcap & HWCAP_DCPOP)
setCPUFeature(FEAT_DPB);
if (hwcap & HWCAP_LRCPC)
setCPUFeature(FEAT_RCPC);
if (hwcap & HWCAP_ILRCPC)
setCPUFeature(FEAT_RCPC2);
if (hwcap2 & HWCAP2_LRCPC3)
setCPUFeature(FEAT_RCPC3);
if (hwcap2 & HWCAP2_BF16)
setCPUFeature(FEAT_BF16);
if (hwcap2 & HWCAP2_SVEBF16)
setCPUFeature(FEAT_SVE_BF16);
if (hwcap & HWCAP_SVE)
setCPUFeature(FEAT_SVE);
if (hwcap2 & HWCAP2_SVE2)
setCPUFeature(FEAT_SVE2);
if (hwcap & HWCAP_SHA3)
setCPUFeature(FEAT_SHA3);
setCPUFeature(FEAT_INIT);

__atomic_store_n(&__aarch64_cpu_features.features, feat, __ATOMIC_RELAXED);
}
4 changes: 2 additions & 2 deletions compiler-rt/lib/builtins/cpu_model/aarch64/fmv/sysauxv.inc
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
void __init_cpu_features_resolver(unsigned long hwcap,
const __ifunc_arg_t *arg) {
if (__aarch64_cpu_features.features)
if (__atomic_load_n(&__aarch64_cpu_features.features, __ATOMIC_RELAXED))
return;
__init_cpu_features_constructor(hwcap, arg);
}

void CONSTRUCTOR_ATTRIBUTE __init_cpu_features(void) {
// CPU features already initialized.
if (__aarch64_cpu_features.features)
if (__atomic_load_n(&__aarch64_cpu_features.features, __ATOMIC_RELAXED))
return;

unsigned long hwcap = getauxval(AT_HWCAP);
Expand Down
6 changes: 6 additions & 0 deletions compiler-rt/lib/builtins/cpu_model/aarch64/hwcap.inc
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,12 @@
#ifndef HWCAP2_SVE_EBF16
#define HWCAP2_SVE_EBF16 (1ULL << 33)
#endif
#ifndef HWCAP2_SME2
#define HWCAP2_SME2 (1UL << 37)
#endif
#ifndef HWCAP2_MOPS
#define HWCAP2_MOPS (1ULL << 43)
#endif
#ifndef HWCAP2_LRCPC3
#define HWCAP2_LRCPC3 (1UL << 46)
#endif
522 changes: 291 additions & 231 deletions compiler-rt/lib/dfsan/dfsan_custom.cpp

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions compiler-rt/lib/gwp_asan/guarded_pool_allocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ void GuardedPoolAllocator::init(const options::Options &Opts) {
Check(Opts.MaxSimultaneousAllocations >= 0,
"GWP-ASan Error: MaxSimultaneousAllocations is < 0.");

Check(SingletonPtr == nullptr,
"There's already a live GuardedPoolAllocator!");
SingletonPtr = this;
Backtrace = Opts.Backtrace;

Expand Down Expand Up @@ -158,6 +160,7 @@ void GuardedPoolAllocator::uninitTestOnly() {
FreeSlots = nullptr;
}
*getThreadLocals() = ThreadLocalPackedVariables();
SingletonPtr = nullptr;
}

// Note, minimum backing allocation size in GWP-ASan is always one page, and
Expand Down
1 change: 1 addition & 0 deletions compiler-rt/lib/gwp_asan/optional/segv_handler_posix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ void installSignalHandlers(gwp_asan::GuardedPoolAllocator *GPA, Printf_t Printf,
Action.sa_flags = SA_SIGINFO;
sigaction(SIGSEGV, &Action, &PreviousHandler);
SignalHandlerInstalled = true;
HasReportedBadPoolAccess = false;
}

void uninstallSignalHandlers() {
Expand Down
9 changes: 0 additions & 9 deletions compiler-rt/lib/gwp_asan/tests/harness.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,6 @@

#include <string>

namespace gwp_asan {
namespace test {
bool OnlyOnce() {
static int x = 0;
return !x++;
}
} // namespace test
} // namespace gwp_asan

// Optnone to ensure that the calls to these functions are not optimized away,
// as we're looking for them in the backtraces.
__attribute__((optnone)) char *
Expand Down
14 changes: 0 additions & 14 deletions compiler-rt/lib/gwp_asan/tests/harness.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ namespace test {
// `optional/printf_sanitizer_common.cpp` which supplies the __sanitizer::Printf
// for this purpose.
Printf_t getPrintfFunction();

// First call returns true, all the following calls return false.
bool OnlyOnce();

}; // namespace test
}; // namespace gwp_asan

Expand All @@ -57,10 +53,7 @@ class DefaultGuardedPoolAllocator : public ::testing::Test {
public:
void SetUp() override {
gwp_asan::options::Options Opts;
Opts.setDefaults();
MaxSimultaneousAllocations = Opts.MaxSimultaneousAllocations;

Opts.InstallForkHandlers = gwp_asan::test::OnlyOnce();
GPA.init(Opts);
}

Expand All @@ -78,12 +71,8 @@ class CustomGuardedPoolAllocator : public ::testing::Test {
InitNumSlots(decltype(gwp_asan::options::Options::MaxSimultaneousAllocations)
MaxSimultaneousAllocationsArg) {
gwp_asan::options::Options Opts;
Opts.setDefaults();

Opts.MaxSimultaneousAllocations = MaxSimultaneousAllocationsArg;
MaxSimultaneousAllocations = MaxSimultaneousAllocationsArg;

Opts.InstallForkHandlers = gwp_asan::test::OnlyOnce();
GPA.init(Opts);
}

Expand All @@ -100,10 +89,7 @@ class BacktraceGuardedPoolAllocator
public:
void SetUp() override {
gwp_asan::options::Options Opts;
Opts.setDefaults();

Opts.Backtrace = gwp_asan::backtrace::getBacktraceFunction();
Opts.InstallForkHandlers = gwp_asan::test::OnlyOnce();
GPA.init(Opts);

// In recoverable mode, capture GWP-ASan logs to an internal buffer so that
Expand Down
1 change: 1 addition & 0 deletions compiler-rt/lib/gwp_asan/tests/late_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ TEST(LateInit, CheckLateInitIsOK) {

GPA.init(Opts);
EXPECT_TRUE(GPA.shouldSample());
GPA.uninitTestOnly();
}
7 changes: 0 additions & 7 deletions compiler-rt/lib/hwasan/hwasan_flags.inc
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,3 @@ HWASAN_FLAG(bool, malloc_bisect_dump, false,
// are untagged before the call.
HWASAN_FLAG(bool, fail_without_syscall_abi, true,
"Exit if fail to request relaxed syscall ABI.")

HWASAN_FLAG(
uptr, fixed_shadow_base, -1,
"If not -1, HWASan will attempt to allocate the shadow at this address, "
"instead of choosing one dynamically."
"Tip: this can be combined with the compiler option, "
"-hwasan-mapping-offset, to optimize the instrumentation.")
8 changes: 2 additions & 6 deletions compiler-rt/lib/hwasan/hwasan_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,8 @@ static uptr GetHighMemEnd() {
}

static void InitializeShadowBaseAddress(uptr shadow_size_bytes) {
if (flags()->fixed_shadow_base != (uptr)-1) {
__hwasan_shadow_memory_dynamic_address = flags()->fixed_shadow_base;
} else {
__hwasan_shadow_memory_dynamic_address =
FindDynamicShadowStart(shadow_size_bytes);
}
__hwasan_shadow_memory_dynamic_address =
FindDynamicShadowStart(shadow_size_bytes);
}

static void MaybeDieIfNoTaggingAbi(const char *message) {
Expand Down
6 changes: 3 additions & 3 deletions compiler-rt/test/asan/TestCases/Linux/stack-trace-dlclose.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,6 @@ int main(int argc, char **argv) {
}
#endif

// CHECK: {{ #[0-9]+ 0x.* in (__interceptor_)?malloc}}
// CHECK: {{ #[0-9]+ 0x.* \(<unknown module>\)}}
// CHECK: {{ #[0-9]+ 0x.* in main}}
// CHECK: {{ #0 0x.* in (__interceptor_)?malloc}}
// CHECK: {{ #1 0x.* \(<unknown module>\)}}
// CHECK: {{ #2 0x.* in main}}
4 changes: 2 additions & 2 deletions compiler-rt/test/asan/TestCases/Posix/strndup_oob_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ int main(int argc, char **argv) {
char *copy = strndup(kString, 2);
int x = copy[2 + argc]; // BOOM
// CHECK: AddressSanitizer: heap-buffer-overflow
// CHECK: #{{[0-9]+}} {{.*}}main {{.*}}strndup_oob_test.cpp:[[@LINE-2]]
// CHECK: #0 {{.*}}main {{.*}}strndup_oob_test.cpp:[[@LINE-2]]
// CHECK-LABEL: allocated by thread T{{.*}} here:
// CHECK: #{{[0-9]+}} {{.*}}strndup
// CHECK: #{{[01]}} {{.*}}strndup
// CHECK: #{{.*}}main {{.*}}strndup_oob_test.cpp:[[@LINE-6]]
// CHECK-LABEL: SUMMARY
// CHECK: strndup_oob_test.cpp:[[@LINE-7]]
Expand Down
4 changes: 2 additions & 2 deletions compiler-rt/test/asan/TestCases/calloc-overflow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
int main() {
void *p = calloc(-1, 1000);
// CHECK: {{ERROR: AddressSanitizer: calloc parameters overflow: count \* size \(.* \* 1000\) cannot be represented in type size_t}}
// CHECK: {{#[0-9]+ 0x.* in calloc .*.cpp}}
// CHECK: {{#[0-9]+ 0x.* in main .*calloc-overflow.cpp:}}[[@LINE-3]]
// CHECK: {{#0 0x.* in .*calloc}}
// CHECK: {{#[1-3] 0x.* in main .*calloc-overflow.cpp:}}[[@LINE-3]]
// CHECK: SUMMARY: AddressSanitizer: calloc-overflow

printf("calloc returned: %zu\n", (size_t)p);
Expand Down
8 changes: 4 additions & 4 deletions compiler-rt/test/asan/TestCases/debug_stacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,11 @@ int main() {
// CHECK: ERROR: AddressSanitizer: heap-use-after-free
// CHECK: WRITE of size 1 at 0x{{.*}}
// CHECK: freed by thread T0 here:
// CHECK: #{{[0-9]+}} [[FREE_FRAME_0]]
// CHECK: #{{[0-9]+}} [[FREE_FRAME_1]]
// CHECK: #0 [[FREE_FRAME_0]]
// CHECK: #1 [[FREE_FRAME_1]]
// CHECK: previously allocated by thread T0 here:
// CHECK: #{{[0-9+]}} [[ALLOC_FRAME_0]]
// CHECK: #{{[0-9+]}} [[ALLOC_FRAME_1]]
// CHECK: #0 [[ALLOC_FRAME_0]]
// CHECK: #1 [[ALLOC_FRAME_1]]

return 0;
}
6 changes: 3 additions & 3 deletions compiler-rt/test/asan/TestCases/double-free.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ int main(int argc, char **argv) {
free(x);
free(x + argc - 1); // BOOM
// CHECK: AddressSanitizer: attempting double-free{{.*}}in thread T0
// CHECK: #{{[0-9]+}} 0x{{.*}} in {{.*}}free
// CHECK: #{{[0-9]+}} 0x{{.*}} in main {{.*}}double-free.cpp:[[@LINE-3]]
// CHECK: #0 0x{{.*}} in {{.*}}free
// CHECK: #{{[1-3]}} 0x{{.*}} in main {{.*}}double-free.cpp:[[@LINE-3]]
// CHECK: freed by thread T0 here:
// MALLOC-CTX: #0 0x{{.*}} in {{.*}}free
// MALLOC-CTX: #{{[0-9]+}} 0x{{.*}} in main {{.*}}double-free.cpp:[[@LINE-7]]
// MALLOC-CTX: #{{[1-3]}} 0x{{.*}} in main {{.*}}double-free.cpp:[[@LINE-7]]
// CHECK: allocated by thread T0 here:
// MALLOC-CTX: double-free.cpp:[[@LINE-12]]
// CHECK-RECOVER: AddressSanitizer: attempting double-free{{.*}}in thread T0
Expand Down
4 changes: 2 additions & 2 deletions compiler-rt/test/asan/TestCases/malloc-size-too-big.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ static const size_t kMaxAllowedMallocSizePlusOne =
int main() {
void *p = malloc(kMaxAllowedMallocSizePlusOne);
// CHECK: {{ERROR: AddressSanitizer: requested allocation size .* \(.* after adjustments for alignment, red zones etc\.\) exceeds maximum supported size}}
// CHECK: {{#[0-9] 0x.* in .*malloc}}
// CHECK: {{#[0-9] 0x.* in main .*malloc-size-too-big.cpp:}}[[@LINE-3]]
// CHECK: {{#0 0x.* in .*malloc}}
// CHECK: {{#[1-3] 0x.* in main .*malloc-size-too-big.cpp:}}[[@LINE-3]]
// CHECK: SUMMARY: AddressSanitizer: allocation-size-too-big

printf("malloc returned: %zu\n", (size_t)p);
Expand Down
6 changes: 3 additions & 3 deletions compiler-rt/test/asan/TestCases/strcpy-overlap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ __attribute__((noinline)) void bad_function() {
char buffer[] = "hello";
// CHECK: strcpy-param-overlap: memory ranges
// CHECK: [{{0x.*,[ ]*0x.*}}) and [{{0x.*,[ ]*0x.*}}) overlap
// CHECK: {{#[0-9]+ 0x.* in .*strcpy .*.cpp}}
// CHECK: {{#[0-9]+ 0x.* in bad_function.*strcpy-overlap.cpp:}}[[@LINE+2]]
// CHECK: {{#[0-9]+ 0x.* in main .*strcpy-overlap.cpp:}}[[@LINE+5]]
// CHECK: {{#0 0x.* in .*strcpy}}
// CHECK: {{#1 0x.* in bad_function.*strcpy-overlap.cpp:}}[[@LINE+2]]
// CHECK: {{#2 0x.* in main .*strcpy-overlap.cpp:}}[[@LINE+5]]
strcpy(buffer, buffer + 1); // BOOM
}

Expand Down
2 changes: 1 addition & 1 deletion compiler-rt/test/asan/TestCases/strdup_oob_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ int main(int argc, char **argv) {
// CHECK: AddressSanitizer: heap-buffer-overflow
// CHECK: #0 {{.*}}main {{.*}}strdup_oob_test.cpp:[[@LINE-2]]
// CHECK-LABEL: allocated by thread T{{.*}} here:
// CHECK: #{{[0-9]}}+ {{.*}}strdup
// CHECK: #{{[01]}} {{.*}}strdup
// CHECK: #{{.*}}main {{.*}}strdup_oob_test.cpp:[[@LINE-6]]
// CHECK-LABEL: SUMMARY
// CHECK: strdup_oob_test.cpp:[[@LINE-7]]
Expand Down
8 changes: 4 additions & 4 deletions compiler-rt/test/asan/TestCases/strncpy-overflow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ int main(int argc, char **argv) {
char *short_buffer = (char*)malloc(9);
strncpy(short_buffer, hello, 10); // BOOM
// CHECK: {{WRITE of size 10 at 0x.* thread T0}}
// CHECK: {{ #[0-9]+ 0x.* in .*strncpy .*.cpp}}
// CHECK: {{ #[0-9]+ 0x.* in main .*strncpy-overflow.cpp:}}[[@LINE-3]]
// CHECK: {{ #0 0x.* in .*strncpy}}
// CHECK: {{ #1 0x.* in main .*strncpy-overflow.cpp:}}[[@LINE-3]]
// CHECK: {{0x.* is located 0 bytes after 9-byte region}}
// CHECK: {{allocated by thread T0 here:}}
// CHECK: {{ #[0-9]+ 0x.* in .*malloc}}
// CHECK: {{ #[0-9]+ 0x.* in main .*strncpy-overflow.cpp:}}[[@LINE-8]]
// CHECK: {{ #0 0x.* in .*malloc}}
// CHECK: {{ #[1-3] 0x.* in main .*strncpy-overflow.cpp:}}[[@LINE-8]]
return rval + sink_memory(9, short_buffer);
}
10 changes: 5 additions & 5 deletions compiler-rt/test/asan/TestCases/use-after-free-right.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ int main() {
// CHECK: {{.*ERROR: AddressSanitizer: heap-use-after-free on address}}
// CHECK: {{0x.* at pc 0x.* bp 0x.* sp 0x.*}}
// CHECK: {{WRITE of size 1 at 0x.* thread T0}}
// CHECK: {{ #[0-9]+ 0x.* in main .*use-after-free-right.cpp:}}[[@LINE-4]]
// CHECK: {{ #0 0x.* in main .*use-after-free-right.cpp:}}[[@LINE-4]]
// CHECK: {{0x.* is located 0 bytes inside of 1-byte region .0x.*,0x.*}}
// CHECK: {{freed by thread T0 here:}}
// CHECK: {{ #[0-9]+ 0x.* in .*free .*.cpp}}
// CHECK: {{ #[0-9]+ 0x.* in main .*use-after-free-right.cpp:}}[[@LINE-9]]
// CHECK: {{ #0 0x.* in .*free}}
// CHECK: {{ #[1-3] 0x.* in main .*use-after-free-right.cpp:}}[[@LINE-9]]

// CHECK: {{previously allocated by thread T0 here:}}
// CHECK: {{ #[0-9]+ 0x.* in .*malloc}}
// CHECK: {{ #[0-9]+ 0x.* in main .*use-after-free-right.cpp:}}[[@LINE-14]]
// CHECK: {{ #0 0x.* in .*malloc}}
// CHECK: {{ #[1-3] 0x.* in main .*use-after-free-right.cpp:}}[[@LINE-14]]
}
10 changes: 5 additions & 5 deletions compiler-rt/test/asan/TestCases/use-after-free.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ int main() {
// CHECK: {{.*ERROR: AddressSanitizer: heap-use-after-free on address}}
// CHECK: {{0x.* at pc 0x.* bp 0x.* sp 0x.*}}
// CHECK: {{READ of size 1 at 0x.* thread T0}}
// CHECK: {{ #[0-9]+ 0x.* in main .*use-after-free.cpp:}}[[@LINE-4]]
// CHECK: {{ #0 0x.* in main .*use-after-free.cpp:}}[[@LINE-4]]
// CHECK: {{0x.* is located 5 bytes inside of 10-byte region .0x.*,0x.*}}
// CHECK: {{freed by thread T0 here:}}
// CHECK: {{ #[0-9]+ 0x.* in .*free}}
// CHECK: {{ #[0-9]+ 0x.* in main .*use-after-free.cpp:}}[[@LINE-9]]
// CHECK: {{ #0 0x.* in .*free}}
// CHECK: {{ #[1-3] 0x.* in main .*use-after-free.cpp:}}[[@LINE-9]]

// CHECK: {{previously allocated by thread T0 here:}}
// CHECK: {{ #[0-9]+ 0x.* in .*malloc}}
// CHECK: {{ #[0-9]+ 0x.* in main .*use-after-free.cpp:}}[[@LINE-14]]
// CHECK: {{ #0 0x.* in .*malloc}}
// CHECK: {{ #[1-3] 0x.* in main .*use-after-free.cpp:}}[[@LINE-14]]
// CHECK: Shadow byte legend (one shadow byte represents {{[0-9]+}} application bytes):
// CHECK: Global redzone:
// CHECK: ASan internal:
Expand Down
2 changes: 1 addition & 1 deletion compiler-rt/test/dfsan/custom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2280,7 +2280,7 @@ void test_sscanf() {
// %n, %s, %d, %f, and %% already tested
}

// Tested by a seperate source file. This empty function is here to appease the
// Tested by a separate source file. This empty function is here to appease the
// check-wrappers script.
void test_fork() {}

Expand Down
111 changes: 102 additions & 9 deletions compiler-rt/test/dfsan/sscanf.c
Original file line number Diff line number Diff line change
@@ -1,18 +1,111 @@
// RUN: %clang_dfsan %s -o %t && %run %t
// XFAIL: *

#include <assert.h>
#include <stdio.h>

int main(int argc, char *argv[]) {
char buf[256] = "10000000000-100000000000 rw-p 00000000 00:00 0";
long rss = 0;
// This test exposes a bug in DFSan's sscanf, that leads to flakiness
// in release_shadow_space.c (see
// https://github.com/llvm/llvm-project/issues/91287)
if (sscanf(buf, "Garbage text before, %ld, Garbage text after", &rss) == 1) {
printf("Error: matched %ld\n", rss);
return 1;
{
char buf[256] = "10000000000-100000000000 rw-p 00000000 00:00 0";
long rss = 0;
// This test exposes a bug in DFSan's sscanf, that leads to flakiness
// in release_shadow_space.c (see
// https://github.com/llvm/llvm-project/issues/91287)
int r = sscanf(buf, "Garbage text before, %ld, Garbage text after", &rss);
assert(r == 0);
}

// Testing other variations of sscanf behavior.
{
int a = 0;
int b = 0;
int r = sscanf("abc42 cat 99", "abc%d cat %d", &a, &b);
assert(a == 42);
assert(b == 99);
assert(r == 2);
}

{
int a = 0;
int b = 0;
int r = sscanf("abc42 cat 99", "abc%d dog %d", &a, &b);
assert(a == 42);
assert(r == 1);
}

{
int a = 0;
int b = 0;
int r = sscanf("abx42 dog 99", "abc%d dog %d", &a, &b);
assert(r == 0);
}

{
int r = sscanf("abx", "abc");
assert(r == 0);
}

{
int r = sscanf("abc", "abc");
assert(r == 0);
}

{
int n = 0;
int r = sscanf("abc", "abc%n", &n);
assert(n == 3);
assert(r == 0);
}

{
int n = 1234;
int r = sscanf("abxy", "abcd%n", &n);
assert(n == 1234);
assert(r == 0);
}

{
int a = 0;
int n = 1234;
int r = sscanf("abcd99", "abcd%d%n", &a, &n);
assert(a == 99);
assert(n == 6);
assert(r == 1);
}

{
int n = 1234;
int r = sscanf("abcdsuffix", "abcd%n", &n);
assert(n == 4);
assert(r == 0);
}

{
int n = 1234;
int r = sscanf("abxxsuffix", "abcd%n", &n);
assert(n == 1234);
assert(r == 0);
}

{
int a = 0;
int b = 0;
int n = 1234;
int r = sscanf("abcd99 xy100", "abcd%d xy%d%n", &a, &b, &n);
assert(a == 99);
assert(b == 100);
assert(n == 12);
assert(r == 2);
}

{
int a = 0;
int b = 0;
int n = 1234;
int r = sscanf("abcd99 xy100", "abcd%d zz%d%n", &a, &b, &n);
assert(a == 99);
assert(b == 0);
assert(n == 1234);
assert(r == 1);
}

return 0;
Expand Down
Loading