Skip to content

Commit b9a3e99

Browse files
authored
[Clang]Ensure correct handling of cleanup access control (#135668) (#135686)
The P2719 implementation refactored diagnostics for cleanup delete, and as part of that I attempted to fix handling of inaccessible cleanup operator delete. Alas the new branch was incorrect as it was performing an implicit bool conversion, which resulted in friend accessible cleanup operators incorrectly being considered erroneous and the allocation path errored out. This error however did not get diagnosed, so the result was and so we did not actually error out before codegen. Added both Sema and CodeGen tests to cover this.
1 parent 76db259 commit b9a3e99

File tree

3 files changed

+66
-2
lines changed

3 files changed

+66
-2
lines changed

clang/lib/Sema/SemaExprCXX.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1929,8 +1929,9 @@ static bool CheckDeleteOperator(Sema &S, SourceLocation StartLoc,
19291929
}
19301930
return true;
19311931
}
1932-
1933-
return S.CheckAllocationAccess(StartLoc, Range, NamingClass, Decl, Diagnose);
1932+
Sema::AccessResult Accessible =
1933+
S.CheckAllocationAccess(StartLoc, Range, NamingClass, Decl, Diagnose);
1934+
return Accessible == Sema::AR_inaccessible;
19341935
}
19351936

19361937
/// Select the correct "usual" deallocation function to use from a selection of

clang/test/CodeGenCXX/bug135668.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// RUN: %clang_cc1 %s -triple arm64-apple-macosx -emit-llvm -fcxx-exceptions -fexceptions -std=c++23 -o - | FileCheck %s
2+
3+
class TestClass {
4+
public:
5+
TestClass();
6+
int field = 0;
7+
friend class Foo;
8+
static void * operator new(unsigned long size);
9+
private:
10+
static void operator delete(void *p);
11+
};
12+
13+
class Foo {
14+
public:
15+
int test_method();
16+
};
17+
18+
int Foo::test_method() {
19+
TestClass *obj = new TestClass() ;
20+
return obj->field;
21+
}
22+
23+
// CHECK-LABEL: define noundef i32 @_ZN3Foo11test_methodEv
24+
// CHECK: [[THIS_ADDR:%.*]] = alloca ptr, align 8
25+
// CHECK: [[OBJ:%.*]] = alloca ptr, align 8
26+
// CHECK: store ptr %this, ptr [[THIS_ADDR]], align 8
27+
// CHECK: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
28+
// CHECK: [[ALLOCATION:%.*]] = call noundef ptr @_ZN9TestClassnwEm(i64 noundef 4)
29+
// CHECK: [[INITIALIZEDOBJ:%.*]] = invoke noundef ptr @_ZN9TestClassC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ALLOCATION]])
30+
// CHECK-NEXT: to label %[[INVOKE_CONT:.*]] unwind label %[[LPAD:.*]]
31+
// CHECK: [[INVOKE_CONT]]:
32+
// CHECK: store ptr [[ALLOCATION]], ptr [[OBJ]], align 8
33+
// CHECK: [[OBJPTR:%.*]] = load ptr, ptr [[OBJ]], align 8
34+
// CHECK: [[FIELDPTR:%.*]] = getelementptr inbounds nuw %class.TestClass, ptr [[OBJPTR]], i32 0, i32 0
35+
// CHECK: [[FIELD:%.*]] = load i32, ptr [[FIELDPTR]], align 4
36+
// CHECK: ret i32 [[FIELD]]
37+
// CHECK: [[LPAD]]:
38+
// CHECK: call void @_ZN9TestClassdlEPv(ptr noundef [[ALLOCATION]]) #3

clang/test/SemaCXX/bug135668.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %clang_cc1 -triple arm64-apple-macosx -Wall -fsyntax-only -verify %s -std=c++26 -fexceptions -fcxx-exceptions
2+
// expected-no-diagnostics
3+
4+
// This test makes sure that we don't erroneously consider an accessible operator
5+
// delete to be inaccessible, and then discard the entire new expression.
6+
7+
class TestClass {
8+
public:
9+
TestClass();
10+
int field = 0;
11+
friend class Foo;
12+
static void * operator new(unsigned long size);
13+
private:
14+
static void operator delete(void *p);
15+
};
16+
17+
class Foo {
18+
public:
19+
int test_method();
20+
};
21+
22+
int Foo::test_method() {
23+
TestClass *obj = new TestClass() ;
24+
return obj->field;
25+
}

0 commit comments

Comments
 (0)