brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.9 KiB · d1e603f Raw
88 lines · cpp
1// REQUIRES: staticanalyzer2//3// RUN: rm -rf %t4// RUN: mkdir -p %t5// RUN: split-file --leading-lines %s %t6//7// Prepare the BMIs.8// RUN: %clang_cc1 -std=c++20 -emit-module-interface -o %t/mod_a-part1.pcm %t/mod_a-part1.cppm9// RUN: %clang_cc1 -std=c++20 -emit-module-interface -o %t/mod_a-part2.pcm %t/mod_a-part2.cppm10// RUN: %clang_cc1 -std=c++20 -emit-module-interface -o %t/mod_a.pcm %t/mod_a.cppm -fmodule-file=mod_a:part2=%t/mod_a-part2.pcm -fmodule-file=mod_a:part1=%t/mod_a-part1.pcm11// RUN: %clang_cc1 -std=c++20 -emit-module-interface -o %t/mod_b.pcm %t/mod_b.cppm -fmodule-file=mod_a:part2=%t/mod_a-part2.pcm -fmodule-file=mod_a=%t/mod_a.pcm -fmodule-file=mod_a:part1=%t/mod_a-part1.pcm12 13// Trigger the construction of the parent map (which is necessary to trigger the bug this regression test is for) using ArrayBoundV2 checker:14// RUN: %clang_cc1 -std=c++20 -analyze -analyzer-checker=security,alpha.security -analyzer-output=text %t/test-array-bound-v2.cpp -fmodule-file=mod_a:part2=%t/mod_a-part2.pcm -fmodule-file=mod_a=%t/mod_a.pcm -fmodule-file=mod_a:part1=%t/mod_a-part1.pcm -fmodule-file=mod_b=%t/mod_b.pcm15 16//--- mod_a-part1.cppm17module;18namespace mod_a {19template <int> struct Important;20}21 22namespace mod_a {23Important<0>& instantiate1();24} // namespace mod_a25export module mod_a:part1;26 27export namespace mod_a {28using ::mod_a::instantiate1;29}30 31//--- mod_a-part2.cppm32module;33namespace mod_a {34template <int> struct Important;35}36 37namespace mod_a {38template <int N> Important<N>& instantiate2();39namespace part2InternalInstantiations {40// During the construction of the parent map, we iterate over ClassTemplateDecl::specializations() for 'Important'.41// After GH119333, the following instantiations get loaded between the call to spec_begin() and spec_end().42// This used to invalidate the begin iterator returned by spec_begin() by the time the end iterator is returned.43// This is a regression test for that.44Important<1> fn1();45Important<2> fn2();46Important<3> fn3();47Important<4> fn4();48Important<5> fn5();49Important<6> fn6();50Important<7> fn7();51Important<8> fn8();52Important<9> fn9();53Important<10> fn10();54Important<11> fn11();55}56} // namespace mod_a57export module mod_a:part2;58 59export namespace mod_a {60using ::mod_a::instantiate2;61}62 63//--- mod_a.cppm64export module mod_a;65export import :part1;66export import :part2;67 68//--- mod_b.cppm69export module mod_b;70import mod_a;71 72void a() {73  mod_a::instantiate1();74  mod_a::instantiate2<42>();75}76 77//--- test-array-bound-v2.cpp78import mod_b;79 80extern void someFunc(char* first, char* last);81void triggerParentMapContextCreationThroughArrayBoundV2() {82  // This code currently causes the ArrayBoundV2 checker to create the ParentMapContext.83  // Once it detects an access to buf[100], the checker looks through the parents to find '&' operator.84  // (this is needed since taking the address of past-the-end pointer is allowed by the checker)85  char buf[100];86  someFunc(&buf[0], &buf[100]);87}88