Skip to content

Commit db47939

Browse files
authored
Merge branch 'llvm:main' into main
2 parents 5ef53b1 + 9fc152d commit db47939

Some content is hidden

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

52 files changed

+475
-230
lines changed

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4557,6 +4557,9 @@ Sema::CheckConceptTemplateId(const CXXScopeSpec &SS,
45574557
const TemplateArgumentListInfo *TemplateArgs) {
45584558
assert(NamedConcept && "A concept template id without a template?");
45594559

4560+
if (NamedConcept->isInvalidDecl())
4561+
return ExprError();
4562+
45604563
llvm::SmallVector<TemplateArgument, 4> SugaredConverted, CanonicalConverted;
45614564
if (CheckTemplateArgumentList(
45624565
NamedConcept, ConceptNameInfo.getLoc(),

clang/lib/Serialization/ASTReaderDecl.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2663,7 +2663,8 @@ void ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
26632663

26642664
D->setDeclaredWithTypename(Record.readInt());
26652665

2666-
if (D->hasTypeConstraint()) {
2666+
bool TypeConstraintInitialized = D->hasTypeConstraint() && Record.readBool();
2667+
if (TypeConstraintInitialized) {
26672668
ConceptReference *CR = nullptr;
26682669
if (Record.readBool())
26692670
CR = Record.readConceptReference();

clang/lib/Serialization/ASTWriterDecl.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1951,7 +1951,8 @@ void ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
19511951
Record.push_back(D->wasDeclaredWithTypename());
19521952

19531953
const TypeConstraint *TC = D->getTypeConstraint();
1954-
assert((bool)TC == D->hasTypeConstraint());
1954+
if (D->hasTypeConstraint())
1955+
Record.push_back(/*TypeConstraintInitialized=*/TC != nullptr);
19551956
if (TC) {
19561957
auto *CR = TC->getConceptReference();
19571958
Record.push_back(CR != nullptr);
@@ -1969,7 +1970,7 @@ void ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
19691970
if (OwnsDefaultArg)
19701971
Record.AddTemplateArgumentLoc(D->getDefaultArgument());
19711972

1972-
if (!TC && !OwnsDefaultArg &&
1973+
if (!D->hasTypeConstraint() && !OwnsDefaultArg &&
19731974
D->getDeclContext() == D->getLexicalDeclContext() &&
19741975
!D->isInvalidDecl() && !D->hasAttrs() &&
19751976
!D->isTopLevelDeclInObjCContainer() && !D->isImplicit() &&

clang/test/CodeGen/tbaa-pointers.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,24 @@ void unamed_struct_typedef(TypedefS *ptr) {
205205
ptr->i1 = 0;
206206
}
207207

208+
int void_ptrs(void **ptr) {
209+
// COMMON-LABEL: define i32 @void_ptrs(
210+
// COMMON-SAME: ptr noundef [[PTRA:%.+]])
211+
// COMMON: [[PTR_ADDR:%.+]] = alloca ptr, align 8
212+
// DISABLE-NEXT: store ptr [[PTRA]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
213+
// DISABLE-NEXT: [[L0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
214+
// DISABLE-NEXT: [[L1:%.+]] = load ptr, ptr [[L0]], align 8, !tbaa [[ANYPTR]]
215+
// DEFAULT-NEXT: store ptr [[PTRA]], ptr [[PTR_ADDR]], align 8, !tbaa [[P2VOID:!.+]]
216+
// DEFAULT-NEXT: [[L0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[P2VOID]]
217+
// DEFAULT-NEXT: [[L1:%.+]] = load ptr, ptr [[L0]], align 8, !tbaa [[P1VOID:!.+]]
218+
// COMMON-NEXT: [[BOOL:%.+]] = icmp ne ptr [[L1]], null
219+
// COMMON-NEXT: [[BOOL_EXT:%.+]] = zext i1 [[BOOL]] to i64
220+
// COMMON-NEXT: [[COND:%.+]] = select i1 [[BOOL]], i32 0, i32 1
221+
// COMMON-NEXT: ret i32 [[COND]]
222+
223+
return *ptr ? 0 : 1;
224+
}
225+
208226
// DEFAULT: [[P2INT_0]] = !{[[P2INT:!.+]], [[P2INT]], i64 0}
209227
// DEFAULT: [[P2INT]] = !{!"p2 int", [[ANY_POINTER:!.+]], i64 0}
210228
// DISABLE: [[ANYPTR]] = !{[[ANY_POINTER:!.+]], [[ANY_POINTER]], i64 0}
@@ -237,3 +255,7 @@ void unamed_struct_typedef(TypedefS *ptr) {
237255
// COMMON: [[INT_TAG]] = !{[[INT_TY:!.+]], [[INT_TY]], i64 0}
238256
// COMMON: [[INT_TY]] = !{!"int", [[CHAR]], i64 0}
239257
// DEFAULT: [[P1TYPEDEF]] = !{[[ANY_POINTER]], [[ANY_POINTER]], i64 0}
258+
// DEFAULT: [[P2VOID]] = !{[[P2VOID_TY:!.+]], [[P2VOID_TY]], i64 0}
259+
// DEFAULT: [[P2VOID_TY]] = !{!"p2 void", [[ANY_POINTER]], i64 0}
260+
// DEFAULT: [[P1VOID]] = !{[[P1VOID_TY:!.+]], [[P1VOID_TY]], i64 0}
261+
// DEFAULT: [[P1VOID_TY]] = !{!"p1 void", [[ANY_POINTER]], i64 0}

clang/test/SemaTemplate/concepts.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1165,3 +1165,15 @@ concept C = invalid; // expected-error {{use of undeclared identifier 'invalid'}
11651165
bool val2 = C<int>;
11661166

11671167
} // namespace GH109780
1168+
1169+
namespace GH121980 {
1170+
1171+
template <class>
1172+
concept has_member_difference_type; // expected-error {{expected '='}}
1173+
1174+
template <has_member_difference_type> struct incrementable_traits; // expected-note {{declared here}}
1175+
1176+
template <has_member_difference_type Tp>
1177+
struct incrementable_traits<Tp>; // expected-error {{not more specialized than the primary}}
1178+
1179+
}

compiler-rt/lib/tysan/tysan.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,10 +197,14 @@ static void reportError(void *Addr, int Size, tysan_type_descriptor *TD,
197197
Printf("\n");
198198

199199
if (pc) {
200+
uptr top = 0;
201+
uptr bottom = 0;
202+
if (flags().print_stacktrace)
203+
GetThreadStackTopAndBottom(false, &top, &bottom);
200204

201205
bool request_fast = StackTrace::WillUseFastUnwind(true);
202206
BufferedStackTrace ST;
203-
ST.Unwind(kStackTraceMax, pc, bp, 0, 0, 0, request_fast);
207+
ST.Unwind(kStackTraceMax, pc, bp, 0, top, bottom, request_fast);
204208
ST.Print();
205209
} else {
206210
Printf("\n");

compiler-rt/lib/tysan/tysan_flags.inc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,6 @@
1515

1616
// TYSAN_FLAG(Type, Name, DefaultValue, Description)
1717
// See COMMON_FLAG in sanitizer_flags.inc for more details.
18+
19+
TYSAN_FLAG(bool, print_stacktrace, false,
20+
"Include full stacktrace into an error report")
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %clang_tysan -O0 %s -o %t && %run %t >%t.out 2>&1
2+
// RUN: FileCheck --check-prefixes=CHECK,CHECK-SHORT %s < %t.out
3+
4+
// RUN: %env_tysan_opts=print_stacktrace=1 %run %t >%t.out 2>&1
5+
// RUN: FileCheck --check-prefixes=CHECK,CHECK-LONG %s < %t.out
6+
7+
float *P;
8+
void zero_array() {
9+
int i;
10+
for (i = 0; i < 1; ++i)
11+
P[i] = 0.0f;
12+
// CHECK: ERROR: TypeSanitizer: type-aliasing-violation
13+
// CHECK: WRITE of size 4 at {{.*}} with type float accesses an existing object of type p1 float
14+
// CHECK: {{#0 0x.* in zero_array .*print_stacktrace.c:}}[[@LINE-3]]
15+
// CHECK-SHORT-NOT: {{#1 0x.* in main .*print_stacktrace.c}}
16+
// CHECK-LONG-NEXT: {{#1 0x.* in main .*print_stacktrace.c}}
17+
}
18+
19+
int main() {
20+
P = (float *)&P;
21+
zero_array();
22+
}

flang/docs/Extensions.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,11 @@ end
160160
* `<>` as synonym for `.NE.` and `/=`
161161
* `$` and `@` as legal characters in names
162162
* Initialization in type declaration statements using `/values/`
163-
* Saved variables without explicit or default initializers are zero initialized.
163+
* Saved variables without explicit or default initializers are zero initialized,
164+
except for scalar variables from the main program that are not explicitly
165+
initialized or marked with an explicit SAVE attribute (these variables may be
166+
placed on the stack by flang and not zero initialized). It is not advised to
167+
rely on this extension in new code.
164168
* In a saved entity of a type with a default initializer, components without default
165169
values are zero initialized.
166170
* Kind specification with `*`, e.g. `REAL*4`

flang/lib/Optimizer/Transforms/StackArrays.cpp

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,18 @@ std::optional<AllocationState> LatticePoint::get(mlir::Value val) const {
330330
return it->second;
331331
}
332332

333+
static mlir::Value lookThroughDeclaresAndConverts(mlir::Value value) {
334+
while (mlir::Operation *op = value.getDefiningOp()) {
335+
if (auto declareOp = llvm::dyn_cast<fir::DeclareOp>(op))
336+
value = declareOp.getMemref();
337+
else if (auto convertOp = llvm::dyn_cast<fir::ConvertOp>(op))
338+
value = convertOp->getOperand(0);
339+
else
340+
return value;
341+
}
342+
return value;
343+
}
344+
333345
mlir::LogicalResult AllocationAnalysis::visitOperation(
334346
mlir::Operation *op, const LatticePoint &before, LatticePoint *after) {
335347
LLVM_DEBUG(llvm::dbgs() << "StackArrays: Visiting operation: " << *op
@@ -363,10 +375,10 @@ mlir::LogicalResult AllocationAnalysis::visitOperation(
363375
mlir::Value operand = op->getOperand(0);
364376

365377
// Note: StackArrays is scheduled in the pass pipeline after lowering hlfir
366-
// to fir. Therefore, we only need to handle `fir::DeclareOp`s.
367-
if (auto declareOp =
368-
llvm::dyn_cast_if_present<fir::DeclareOp>(operand.getDefiningOp()))
369-
operand = declareOp.getMemref();
378+
// to fir. Therefore, we only need to handle `fir::DeclareOp`s. Also look
379+
// past converts in case the pointer was changed between different pointer
380+
// types.
381+
operand = lookThroughDeclaresAndConverts(operand);
370382

371383
std::optional<AllocationState> operandState = before.get(operand);
372384
if (operandState && *operandState == AllocationState::Allocated) {
@@ -535,17 +547,12 @@ AllocMemConversion::matchAndRewrite(fir::AllocMemOp allocmem,
535547

536548
// remove freemem operations
537549
llvm::SmallVector<mlir::Operation *> erases;
538-
for (mlir::Operation *user : allocmem.getOperation()->getUsers()) {
539-
if (auto declareOp = mlir::dyn_cast_if_present<fir::DeclareOp>(user)) {
540-
for (mlir::Operation *user : declareOp->getUsers()) {
541-
if (mlir::isa<fir::FreeMemOp>(user))
542-
erases.push_back(user);
543-
}
544-
}
545-
546-
if (mlir::isa<fir::FreeMemOp>(user))
547-
erases.push_back(user);
548-
}
550+
mlir::Operation *parent = allocmem->getParentOp();
551+
// TODO: this shouldn't need to be re-calculated for every allocmem
552+
parent->walk([&](fir::FreeMemOp freeOp) {
553+
if (lookThroughDeclaresAndConverts(freeOp->getOperand(0)) == allocmem)
554+
erases.push_back(freeOp);
555+
});
549556

550557
// now we are done iterating the users, it is safe to mutate them
551558
for (mlir::Operation *erase : erases)

0 commit comments

Comments
 (0)