Skip to content

Commit c7c9925

Browse files
Merge branch 'main' into issue_166814
2 parents 5a09a8f + e70e9ec commit c7c9925

File tree

155 files changed

+2316
-1197
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

155 files changed

+2316
-1197
lines changed

clang/Maintainers.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,6 @@ Clang static analyzer
147147
148148
| Balázs Benics
149149
| benicsbalazs\@gmail.com (email), steakhal (Phabricator), steakhal (GitHub)
150-
| balazs.benics\@sonarsource.com (email), balazs-benics-sonarsource (GitHub)
151150
152151
Compiler options
153152
~~~~~~~~~~~~~~~~

clang/docs/analyzer/checkers.rst

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ as error. Specifically on x86/x86-64 target if the pointer address space is
198198
dereference is not defined as error. See `X86/X86-64 Language Extensions
199199
<https://clang.llvm.org/docs/LanguageExtensions.html#memory-references-to-specified-segments>`__
200200
for reference.
201-
201+
202202
If the analyzer option ``suppress-dereferences-from-any-address-space`` is set
203203
to true (the default value), then this checker never reports dereference of
204204
pointers with a specified address space. If the option is set to false, then
@@ -1664,6 +1664,23 @@ Warn on uses of the 'bzero' function.
16641664
bzero(ptr, n); // warn
16651665
}
16661666
1667+
.. _security-insecureAPI-decodeValueOfObjCType:
1668+
1669+
security.insecureAPI.decodeValueOfObjCType (C)
1670+
""""""""""""""""""""""""""""""""""""""""""""""
1671+
Warn on uses of the Objective-C method ``-decodeValueOfObjCType:at:``.
1672+
1673+
.. code-block:: objc
1674+
1675+
void test(NSCoder *decoder) {
1676+
unsigned int x;
1677+
[decoder decodeValueOfObjCType:"I" at:&x]; // warn
1678+
}
1679+
1680+
This diagnostic is emitted only on Apple platforms where the safer
1681+
``-decodeValueOfObjCType:at:size:`` alternative is available
1682+
(iOS 11+, macOS 10.13+, tvOS 11+, watchOS 4.0+).
1683+
16671684
.. _security-insecureAPI-getpw:
16681685
16691686
security.insecureAPI.getpw (C)

clang/lib/CodeGen/CGVTables.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,11 @@ static void resolveTopLevelMetadata(llvm::Function *Fn,
125125
if (!DIS)
126126
return;
127127
auto *NewDIS = llvm::MDNode::replaceWithDistinct(DIS->clone());
128+
// As DISubprogram remapping is avoided, clear retained nodes list of
129+
// cloned DISubprogram from retained nodes local to original DISubprogram.
130+
// FIXME: Thunk function signature is produced wrong in DWARF, as retained
131+
// nodes are not remapped.
132+
NewDIS->replaceRetainedNodes(llvm::MDTuple::get(Fn->getContext(), {}));
128133
VMap.MD()[DIS].reset(NewDIS);
129134

130135
// Find all llvm.dbg.declare intrinsics and resolve the DILocalVariable nodes

clang/test/CodeGenCXX/tmp-md-nodes1.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22
// RUN: %clang_cc1 -O0 -triple %itanium_abi_triple -debug-info-kind=limited -emit-llvm %s -o - | \
33
// RUN: FileCheck %s
44

5+
// Trigger GenerateVarArgsThunk.
6+
// RUN: %clang_cc1 -O0 -triple riscv64-linux-gnu -debug-info-kind=limited -emit-llvm %s -o - | \
7+
// RUN: FileCheck %s
8+
9+
// Check that retainedNodes are properly maintained at function cloning.
10+
// RUN: %clang_cc1 -O1 -triple riscv64-linux-gnu -debug-info-kind=limited -emit-llvm %s -o - | \
11+
// RUN: FileCheck %s --check-prefixes=CHECK,CHECK-DI
12+
513
// This test simply checks that the varargs thunk is created. The failing test
614
// case asserts.
715

@@ -16,3 +24,11 @@ struct CharlieImpl : Charlie, Alpha {
1624
} delta;
1725

1826
// CHECK: define {{.*}} void @_ZThn{{[48]}}_N11CharlieImpl5bravoEz(
27+
28+
// CHECK-DI: distinct !DISubprogram({{.*}}, linkageName: "_ZN11CharlieImpl5bravoEz", {{.*}}, retainedNodes: [[RN1:![0-9]+]]
29+
// A non-empty retainedNodes list of original DISubprogram.
30+
// CHECK-DI: [[RN1]] = !{!{{.*}}}
31+
32+
// CHECK-DI: distinct !DISubprogram({{.*}}, linkageName: "_ZN11CharlieImpl5bravoEz", {{.*}}, retainedNodes: [[EMPTY:![0-9]+]]
33+
// An empty retainedNodes list of cloned DISubprogram.
34+
// CHECK-DI: [[EMPTY]] = !{}

clang/test/CodeGenCXX/tmp-md-nodes2.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22
// RUN: %clang_cc1 -O0 -triple %itanium_abi_triple -debug-info-kind=limited -emit-llvm %s -o - | \
33
// RUN: FileCheck %s
44

5+
// Trigger GenerateVarArgsThunk.
6+
// RUN: %clang_cc1 -O0 -triple riscv64-linux-gnu -debug-info-kind=limited -emit-llvm %s -o - | \
7+
// RUN: FileCheck %s
8+
9+
// Check that retainedNodes are properly maintained at function cloning.
10+
// RUN: %clang_cc1 -O1 -triple riscv64-linux-gnu -debug-info-kind=limited -emit-llvm %s -o - | \
11+
// RUN: FileCheck %s --check-prefixes=CHECK,CHECK-DI
12+
513
// This test simply checks that the varargs thunk is created. The failing test
614
// case asserts.
715

@@ -31,3 +39,11 @@ BOOL CBdVfsImpl::ReqCacheHint( CMsgAgent* p_ma, CACHE_HINT hint, ... ) {
3139
}
3240

3341
// CHECK: define {{.*}} @_ZThn{{[48]}}_N10CBdVfsImpl12ReqCacheHintEP9CMsgAgentN3CFs10CACHE_HINTEz(
42+
43+
// An empty retainedNodes list of cloned DISubprogram.
44+
// CHECK-DI: [[EMPTY:![0-9]+]] = !{}
45+
// CHECK-DI: distinct !DISubprogram({{.*}}, linkageName: "_ZN10CBdVfsImpl12ReqCacheHintEP9CMsgAgentN3CFs10CACHE_HINTEz", {{.*}}, retainedNodes: [[RN1:![0-9]+]]
46+
// A non-empty retainedNodes list of original DISubprogram.
47+
// CHECK-DI: [[RN1]] = !{!{{.*}}}
48+
49+
// CHECK-DI: distinct !DISubprogram({{.*}}, linkageName: "_ZN10CBdVfsImpl12ReqCacheHintEP9CMsgAgentN3CFs10CACHE_HINTEz", {{.*}}, retainedNodes: [[EMPTY]]
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
REQUIRES: x86-registered-target, ld.lld
2+
3+
# Show that the ThinLTO cache works with DTLTO.
4+
5+
RUN: rm -rf %t && split-file %s %t && cd %t
6+
7+
# Compile source files into bitcode files.
8+
RUN: %clang -O2 --target=x86_64-linux-gnu -flto=thin -c foo.c main.c
9+
10+
# Execute the linker and check that the cache is populated.
11+
RUN: %clang -O2 --target=x86_64-linux-gnu -Werror -flto=thin -fuse-ld=lld -nostdlib -e main \
12+
RUN: main.o foo.o -o populate1.elf \
13+
RUN: -Wl,--thinlto-distributor=%python \
14+
RUN: -Wl,--thinlto-distributor-arg=%llvm_src_root/utils/dtlto/local.py \
15+
RUN: -Wl,--thinlto-remote-compiler=%clang \
16+
RUN: -Wl,--thinlto-cache-dir=cache.dir \
17+
RUN: -Wl,--save-temps
18+
19+
# Check that there are two backend compilation jobs occurred.
20+
RUN: grep -wo args populate1.*.dist-file.json | wc -l | grep -qx 3
21+
RUN: ls cache.dir/llvmcache.timestamp
22+
RUN: ls cache.dir | count 3
23+
24+
# Execute the linker again and check that a fully populated cache is used correctly,
25+
# i.e., no additional cache entries are created for cache hits.
26+
RUN: %clang -O2 --target=x86_64-linux-gnu -Werror -flto=thin -fuse-ld=lld -nostdlib -e main \
27+
RUN: main.o foo.o -o populate2.elf \
28+
RUN: -Wl,--thinlto-distributor=%python \
29+
RUN: -Wl,--thinlto-distributor-arg=%llvm_src_root/utils/dtlto/local.py \
30+
RUN: -Wl,--thinlto-remote-compiler=%clang \
31+
RUN: -Wl,--thinlto-cache-dir=cache.dir \
32+
RUN: -Wl,--save-temps
33+
34+
# Check that there are no backend compilation jobs occurred.
35+
RUN: grep -wo args populate2.*.dist-file.json | wc -l | grep -qx 1
36+
RUN: ls cache.dir | count 3
37+
38+
RUN: %clang -O0 --target=x86_64-linux-gnu -flto=thin -c foo.c -o foo.O0.o
39+
RUN: %clang -O0 --target=x86_64-linux-gnu -flto=thin -c main.c -o main.O0.o
40+
41+
# Execute the linker again and check that the cache is populated correctly when there
42+
# are no cache hits but there are existing cache entries.
43+
# As a side effect, this also verifies that the optimization level is considered when
44+
# evaluating the cache entry key.
45+
46+
RUN: %clang -O2 --target=x86_64-linux-gnu -Werror -flto=thin -fuse-ld=lld -nostdlib -e main \
47+
RUN: main.O0.o foo.O0.o -o populate3.elf \
48+
RUN: -Wl,--thinlto-distributor=%python \
49+
RUN: -Wl,--thinlto-distributor-arg=%llvm_src_root/utils/dtlto/local.py \
50+
RUN: -Wl,--thinlto-remote-compiler=%clang \
51+
RUN: -Wl,--thinlto-cache-dir=cache.dir \
52+
RUN: -Wl,--save-temps
53+
54+
# Check that there are two new backend compilation jobs occurred.
55+
RUN: grep -wo args populate3.*.dist-file.json | wc -l | grep -qx 3
56+
RUN: ls cache.dir | count 5
57+
58+
RUN: %clang -O2 --target=x86_64-linux-gnu -flto=thin -c main-partial.c
59+
60+
# Execute the linker and check that everything works correctly with the partially populated cache;
61+
# One more cache entry should be generated after this run.
62+
63+
RUN: %clang -O2 --target=x86_64-linux-gnu -Werror -flto=thin -fuse-ld=lld -nostdlib -e main \
64+
RUN: main-partial.o foo.o -o main-partial.elf \
65+
RUN: -Wl,--thinlto-distributor=%python \
66+
RUN: -Wl,--thinlto-distributor-arg=%llvm_src_root/utils/dtlto/local.py \
67+
RUN: -Wl,--thinlto-remote-compiler=%clang \
68+
RUN: -Wl,--thinlto-cache-dir=cache.dir \
69+
RUN: -Wl,--save-temps
70+
71+
# Check that there is one new backend compilation jobs occurred.
72+
RUN: grep -wo args main-partial.*.dist-file.json | wc -l | grep -qx 2
73+
RUN: ls cache.dir | count 6
74+
75+
#--- foo.c
76+
volatile int foo_int;
77+
__attribute__((retain)) int foo(int x) { return x + foo_int; }
78+
79+
#--- main.c
80+
extern int foo(int x);
81+
__attribute__((retain)) int main(int argc, char** argv) {
82+
return foo(argc);
83+
}
84+
85+
#--- main-partial.c
86+
extern int foo(int x);
87+
__attribute__((retain)) int main(int argc, char** argv) {
88+
return foo(argc+1);
89+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
REQUIRES: x86-registered-target, ld.lld
2+
3+
# This test verifies that a cache populated by an in-process ThinLTO codegen is
4+
# not reused by an out-of-process (DTLTO) codegen and vice versa.
5+
6+
RUN: rm -rf %t && split-file %s %t && cd %t
7+
8+
# Compile source files into bitcode files.
9+
RUN: %clang -O2 --target=x86_64-linux-gnu -flto=thin -c foo.c main.c
10+
11+
# Execute the linker and check that in-process ThinLTO cache is populated.
12+
RUN: %clang -O2 --target=x86_64-linux-gnu -Werror -flto=thin -fuse-ld=lld -nostdlib -e main \
13+
RUN: main.o foo.o -o main.elf \
14+
RUN: -Wl,--thinlto-cache-dir=cache.dir \
15+
RUN: -Wl,--save-temps
16+
17+
RUN: ls cache.dir/llvmcache.timestamp
18+
RUN: ls cache.dir | count 3
19+
20+
# Execute the linker and check that out-of-process codegen (DTLTO) adds
21+
# additional entries to the cache, implying that in-process and
22+
# out-of-process codegens do not share cache entries.
23+
RUN: %clang -O2 --target=x86_64-linux-gnu -Werror -flto=thin -fuse-ld=lld -nostdlib -e main \
24+
RUN: main.o foo.o -o populate1.elf \
25+
RUN: -Wl,--thinlto-distributor=%python \
26+
RUN: -Wl,--thinlto-distributor-arg=%llvm_src_root/utils/dtlto/local.py \
27+
RUN: -Wl,--thinlto-remote-compiler=%clang \
28+
RUN: -Wl,--thinlto-cache-dir=cache.dir \
29+
RUN: -Wl,--save-temps
30+
31+
# Check that there are two backend compilation jobs occurred.
32+
RUN: grep -wo args populate1.*.dist-file.json | wc -l | grep -qx 3
33+
RUN: ls cache.dir | count 5
34+
35+
# Clean up cache directory.
36+
RUN: rm -rf cache.dir
37+
38+
# Execute the linker and check that out-of-process (DTLTO) cache is populated.
39+
RUN: %clang -O2 --target=x86_64-linux-gnu -Werror -flto=thin -fuse-ld=lld -nostdlib -e main \
40+
RUN: main.o foo.o -o populate2.elf \
41+
RUN: -Wl,--thinlto-distributor=%python \
42+
RUN: -Wl,--thinlto-distributor-arg=%llvm_src_root/utils/dtlto/local.py \
43+
RUN: -Wl,--thinlto-remote-compiler=%clang \
44+
RUN: -Wl,--thinlto-cache-dir=cache.dir \
45+
RUN: -Wl,--save-temps
46+
47+
# Check that there are two backend compilation jobs occurred.
48+
RUN: grep -wo args populate2.*.dist-file.json | wc -l | grep -qx 3
49+
RUN: ls cache.dir/llvmcache.timestamp
50+
RUN: ls cache.dir | count 3
51+
52+
# Execute the linker and check that in-process codegen adds additional entries
53+
# to the cache, implying that in-process and out-of-process codegens do
54+
# not share cache entries.
55+
RUN: %clang -O2 --target=x86_64-linux-gnu -Werror -flto=thin -fuse-ld=lld -nostdlib -e main \
56+
RUN: main.o foo.o -o main.elf \
57+
RUN: -Wl,--thinlto-cache-dir=cache.dir \
58+
RUN: -Wl,--save-temps
59+
60+
RUN: ls cache.dir | count 5
61+
62+
#--- foo.c
63+
volatile int foo_int;
64+
__attribute__((retain)) int foo(int x) { return x + foo_int; }
65+
66+
#--- main.c
67+
extern int foo(int x);
68+
__attribute__((retain)) int main(int argc, char** argv) {
69+
return foo(argc);
70+
}

flang/include/flang/Parser/parse-tree.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5345,21 +5345,21 @@ struct OmpEndLoopDirective : public OmpEndDirective {
53455345
};
53465346

53475347
// OpenMP directives enclosing do loop
5348-
using NestedConstruct =
5349-
std::variant<DoConstruct, common::Indirection<OpenMPLoopConstruct>>;
53505348
struct OpenMPLoopConstruct {
53515349
TUPLE_CLASS_BOILERPLATE(OpenMPLoopConstruct);
53525350
OpenMPLoopConstruct(OmpBeginLoopDirective &&a)
5353-
: t({std::move(a), std::nullopt, std::nullopt}) {}
5351+
: t({std::move(a), Block{}, std::nullopt}) {}
53545352

53555353
const OmpBeginLoopDirective &BeginDir() const {
53565354
return std::get<OmpBeginLoopDirective>(t);
53575355
}
53585356
const std::optional<OmpEndLoopDirective> &EndDir() const {
53595357
return std::get<std::optional<OmpEndLoopDirective>>(t);
53605358
}
5361-
std::tuple<OmpBeginLoopDirective, std::optional<NestedConstruct>,
5362-
std::optional<OmpEndLoopDirective>>
5359+
const DoConstruct *GetNestedLoop() const;
5360+
const OpenMPLoopConstruct *GetNestedConstruct() const;
5361+
5362+
std::tuple<OmpBeginLoopDirective, Block, std::optional<OmpEndLoopDirective>>
53635363
t;
53645364
};
53655365

flang/lib/Lower/OpenMP/OpenMP.cpp

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3962,27 +3962,22 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
39623962

39633963
mlir::Location currentLocation = converter.genLocation(beginSpec.source);
39643964

3965-
auto &optLoopCons =
3966-
std::get<std::optional<parser::NestedConstruct>>(loopConstruct.t);
3967-
if (optLoopCons.has_value()) {
3968-
if (auto *ompNestedLoopCons{
3969-
std::get_if<common::Indirection<parser::OpenMPLoopConstruct>>(
3970-
&*optLoopCons)}) {
3971-
llvm::omp::Directive nestedDirective =
3972-
parser::omp::GetOmpDirectiveName(*ompNestedLoopCons).v;
3973-
switch (nestedDirective) {
3974-
case llvm::omp::Directive::OMPD_tile:
3975-
// Skip OMPD_tile since the tile sizes will be retrieved when
3976-
// generating the omp.loop_nest op.
3977-
break;
3978-
default: {
3979-
unsigned version = semaCtx.langOptions().OpenMPVersion;
3980-
TODO(currentLocation,
3981-
"Applying a loop-associated on the loop generated by the " +
3982-
llvm::omp::getOpenMPDirectiveName(nestedDirective, version) +
3983-
" construct");
3984-
}
3985-
}
3965+
if (const parser::OpenMPLoopConstruct *ompNestedLoopCons =
3966+
loopConstruct.GetNestedConstruct()) {
3967+
llvm::omp::Directive nestedDirective =
3968+
parser::omp::GetOmpDirectiveName(*ompNestedLoopCons).v;
3969+
switch (nestedDirective) {
3970+
case llvm::omp::Directive::OMPD_tile:
3971+
// Skip OMPD_tile since the tile sizes will be retrieved when
3972+
// generating the omp.loop_nest op.
3973+
break;
3974+
default: {
3975+
unsigned version = semaCtx.langOptions().OpenMPVersion;
3976+
TODO(currentLocation,
3977+
"Applying a loop-associated on the loop generated by the " +
3978+
llvm::omp::getOpenMPDirectiveName(nestedDirective, version) +
3979+
" construct");
3980+
}
39863981
}
39873982
}
39883983

flang/lib/Lower/OpenMP/Utils.cpp

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -779,17 +779,9 @@ static void processTileSizesFromOpenMPConstruct(
779779
if (!ompCons)
780780
return;
781781
if (auto *ompLoop{std::get_if<parser::OpenMPLoopConstruct>(&ompCons->u)}) {
782-
const auto &nestedOptional =
783-
std::get<std::optional<parser::NestedConstruct>>(ompLoop->t);
784-
assert(nestedOptional.has_value() &&
785-
"Expected a DoConstruct or OpenMPLoopConstruct");
786-
const auto *innerConstruct =
787-
std::get_if<common::Indirection<parser::OpenMPLoopConstruct>>(
788-
&(nestedOptional.value()));
789-
if (innerConstruct) {
790-
const auto &innerLoopDirective = innerConstruct->value();
782+
if (auto *innerConstruct = ompLoop->GetNestedConstruct()) {
791783
const parser::OmpDirectiveSpecification &innerBeginSpec =
792-
innerLoopDirective.BeginDir();
784+
innerConstruct->BeginDir();
793785
if (innerBeginSpec.DirId() == llvm::omp::Directive::OMPD_tile) {
794786
// Get the size values from parse tree and convert to a vector.
795787
for (const auto &clause : innerBeginSpec.Clauses().v) {

0 commit comments

Comments
 (0)