[clang] c146df9 - [clang][DebugInfo] Emit DW_AT_deleted on any deleted member function

Michael Buch via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 20 01:19:42 PDT 2023


Author: Michael Buch
Date: 2023-06-20T09:19:19+01:00
New Revision: c146df9618764d5548c38ce61edc45147094b26f

URL: https://github.com/llvm/llvm-project/commit/c146df9618764d5548c38ce61edc45147094b26f
DIFF: https://github.com/llvm/llvm-project/commit/c146df9618764d5548c38ce61edc45147094b26f.diff

LOG: [clang][DebugInfo] Emit DW_AT_deleted on any deleted member function

Currently we emit `DW_AT_deleted` for `deleted` special-member
functions (i.e., ctors/dtors). However, in C++ one can mark any
member function as deleted. This patch expands the set of member
functions for which we emit `DW_AT_deleted`.

The DWARFv5 spec section 5.7.8 says:
```
<non-normative>
In C++, a member function may be declared as deleted. This prevents the compiler from
generating a default implementation of a special member function such as a constructor
or destructor, and can affect overload resolution when used on other member functions.
</non-normative>

If the member function entry has been declared as deleted, then that entry has a
DW_AT_deleted attribute.
```

Thus this change is conforming.

Differential Revision: https://reviews.llvm.org/D153282

Added: 
    

Modified: 
    clang/lib/CodeGen/CGDebugInfo.cpp
    clang/test/CodeGenCXX/debug-info-deleted.cpp
    llvm/test/DebugInfo/X86/DW_AT_deleted.ll

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 2fd2227720a2a..f049a682cfed6 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1945,27 +1945,8 @@ llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
     ContainingType = RecordTy;
   }
 
-  // We're checking for deleted C++ special member functions
-  // [Ctors,Dtors, Copy/Move]
-  auto checkAttrDeleted = [&](const auto *Method) {
-    if (Method->getCanonicalDecl()->isDeleted())
-      SPFlags |= llvm::DISubprogram::SPFlagDeleted;
-  };
-
-  switch (Method->getKind()) {
-
-  case Decl::CXXConstructor:
-  case Decl::CXXDestructor:
-    checkAttrDeleted(Method);
-    break;
-  case Decl::CXXMethod:
-    if (Method->isCopyAssignmentOperator() ||
-        Method->isMoveAssignmentOperator())
-      checkAttrDeleted(Method);
-    break;
-  default:
-    break;
-  }
+  if (Method->getCanonicalDecl()->isDeleted())
+    SPFlags |= llvm::DISubprogram::SPFlagDeleted;
 
   if (Method->isNoReturn())
     Flags |= llvm::DINode::FlagNoReturn;

diff  --git a/clang/test/CodeGenCXX/debug-info-deleted.cpp b/clang/test/CodeGenCXX/debug-info-deleted.cpp
index d7d0b6dba49ea..564f7fff00fb9 100644
--- a/clang/test/CodeGenCXX/debug-info-deleted.cpp
+++ b/clang/test/CodeGenCXX/debug-info-deleted.cpp
@@ -11,6 +11,8 @@
 // ATTR: DISubprogram(name: "operator=", linkageName: "_ZN7deletedaSERKS_", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagDeleted
 // ATTR: DISubprogram(name: "deleted", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagDeleted
 // ATTR: DISubprogram(name: "operator=", linkageName: "_ZN7deletedaSEOS_", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagDeleted
+// ATTR: DISubprogram(name: "func", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped | DIFlagRValueReference, spFlags: DISPFlagDeleted
+// ATTR: DISubprogram(name: "bar", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped | DIFlagStaticMember, spFlags: DISPFlagDeleted
 // ATTR: DISubprogram(name: "~deleted", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped,
 class deleted {
 public:
@@ -23,6 +25,9 @@ class deleted {
   deleted(deleted &&) = delete;
   deleted &operator=(deleted &&) = delete;
 
+  void func() && = delete;
+  static int bar() = delete;
+
   ~deleted() = default;
 };
 

diff  --git a/llvm/test/DebugInfo/X86/DW_AT_deleted.ll b/llvm/test/DebugInfo/X86/DW_AT_deleted.ll
index 805655f25813f..0311458ee5223 100644
--- a/llvm/test/DebugInfo/X86/DW_AT_deleted.ll
+++ b/llvm/test/DebugInfo/X86/DW_AT_deleted.ll
@@ -12,6 +12,9 @@
 ; 
 ;   deleted(deleted &&) = delete;
 ;   deleted &operator=(deleted &&) = delete;
+;
+;   void func() && = delete;
+;   static void bar() = delete;
 ; 
 ;   ~deleted() = default;
 ; };
@@ -48,6 +51,16 @@
 ; CHECK-NEXT: DW_AT_name [DW_FORM_strx1]    (indexed (00000008) string = "operator=")
 ; CHECK:  DW_AT_deleted [DW_FORM_flag_present]  (true)
 
+; CHECK: DW_TAG_subprogram [10]
+; CHECK-NEXT: DW_AT_linkage_name [DW_FORM_strx1]    (indexed (0000000b) string = "_ZNO7deleted4funcEv")
+; CHECK-NEXT: DW_AT_name [DW_FORM_strx1]    (indexed (0000000c) string = "func")
+; CHECK:  DW_AT_deleted [DW_FORM_flag_present]  (true)
+
+; CHECK: DW_TAG_subprogram [11]
+; CHECK-NEXT: DW_AT_linkage_name [DW_FORM_strx1]    (indexed (0000000d) string = "_ZN7deleted3barEv")
+; CHECK-NEXT: DW_AT_name [DW_FORM_strx1]    (indexed (0000000e) string = "bar")
+; CHECK:  DW_AT_deleted [DW_FORM_flag_present]  (true)
+
 ; ModuleID = 'debug-info-deleted.cpp'
 source_filename = "debug-info-deleted.cpp"
 target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
@@ -58,8 +71,8 @@ target triple = "x86_64-unknown-linux-gnu"
 ; Function Attrs: noinline nounwind optnone uwtable
 define dso_local void @_Z3foov() #0 !dbg !7 {
   %1 = alloca %class.deleted, align 1
-  call void @llvm.dbg.declare(metadata ptr %1, metadata !10, metadata !DIExpression()), !dbg !34
-  ret void, !dbg !35
+  call void @llvm.dbg.declare(metadata ptr %1, metadata !10, metadata !DIExpression()), !dbg !39
+  ret void, !dbg !40
 }
 
 ; Function Attrs: nounwind readnone speculatable willreturn
@@ -84,7 +97,7 @@ attributes #1 = { nounwind readnone speculatable willreturn }
 !9 = !{null}
 !10 = !DILocalVariable(name: "obj1", scope: !7, file: !1, line: 15, type: !11)
 !11 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "deleted", file: !1, line: 1, size: 8, flags: DIFlagTypePassByReference, elements: !12, identifier: "_ZTS7deleted")
-!12 = !{!13, !17, !22, !26, !30, !33}
+!12 = !{!13, !17, !22, !26, !30, !33, !34, !36}
 !13 = !DISubprogram(name: "deleted", scope: !11, file: !1, line: 3, type: !14, scopeLine: 3, flags: DIFlagPublic | DIFlagPrototyped, spFlags: 0)
 !14 = !DISubroutineType(types: !15)
 !15 = !{null, !16}
@@ -106,5 +119,10 @@ attributes #1 = { nounwind readnone speculatable willreturn }
 !31 = !DISubroutineType(types: !32)
 !32 = !{!25, !16, !29}
 !33 = !DISubprogram(name: "~deleted", scope: !11, file: !1, line: 11, type: !14, scopeLine: 11, flags: DIFlagPublic | DIFlagPrototyped, spFlags: 0)
-!34 = !DILocation(line: 15, column: 13, scope: !7)
-!35 = !DILocation(line: 16, column: 3, scope: !7)
+!34 = !DISubprogram(name: "func", linkageName: "_ZNO7deleted4funcEv", scope: !11, file: !1, line: 13, type: !35, scopeLine: 13, flags: DIFlagPublic | DIFlagPrototyped | DIFlagRValueReference, spFlags: DISPFlagDeleted)                                                                                                                                                                                                           
+!35 = !DISubroutineType(flags: DIFlagRValueReference, types: !15)                                                                                                                                                 
+!36 = !DISubprogram(name: "bar", linkageName: "_ZN7deleted3barEv", scope: !11, file: !1, line: 15, type: !37, scopeLine: 15, flags: DIFlagPublic | DIFlagPrototyped | DIFlagStaticMember, spFlags: DISPFlagDeleted)                                                                                                                                                                                                                 
+!37 = !DISubroutineType(types: !38)
+!38 = !{null}
+!39 = !DILocation(line: 15, column: 13, scope: !7)
+!40 = !DILocation(line: 16, column: 3, scope: !7)


        


More information about the cfe-commits mailing list