From: David Blaikie Date: Sat, 10 May 2014 02:44:57 +0000 (+0000) Subject: Add FIXME describing the limitation of using column info to disambiguate inlining. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=39b4d625bb49250cbaa638be35c2ef0b7c8efb6c;p=clang Add FIXME describing the limitation of using column info to disambiguate inlining. Also tidy up, simplify, and extend the test coverage to demonstrate the limitations. This test should now fail if the bugs are fixed (& hopefully whoever ends up in this situation sees the FIXMEs and realizes that the test needs to be updated to positively test their change that has fixed some or all of these issues). I do wonder whether I could demonstrate breakage without a macro here, but any way I slice it I can't think of a way to get two calls to the same function on the same line/column in non-macro C++ - implicit conversions happen at the same location as an explicit function, but you'd never get an implicit conversion on the result of an explicit call to the same implicit conversion operator (since the value is already converted to the desired result)... git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@208468 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 40870f8906..2be47b46e2 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -2862,6 +2862,10 @@ RValue CodeGenFunction::EmitCallExpr(const CallExpr *E, SourceLocation Loc = E->getLocStart(); // Force column info to be generated so we can differentiate // multiple call sites on the same line in the debug info. + // FIXME: This is insufficient. Two calls coming from the same macro + // expansion will still get the same line/column and break debug info. It's + // possible that LLVM can be fixed to not rely on this uniqueness, at which + // point this workaround can be removed. const FunctionDecl* Callee = E->getDirectCallee(); bool ForceColumnInfo = Callee && Callee->isInlineSpecified(); DI->EmitLocation(Builder, Loc, ForceColumnInfo); @@ -3131,6 +3135,10 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee, // Force column info to differentiate multiple inlined call sites on // the same line, analoguous to EmitCallExpr. + // FIXME: This is insufficient. Two calls coming from the same macro expansion + // will still get the same line/column and break debug info. It's possible + // that LLVM can be fixed to not rely on this uniqueness, at which point this + // workaround can be removed. bool ForceColumnInfo = false; if (const FunctionDecl* FD = dyn_cast_or_null(TargetDecl)) ForceColumnInfo = FD->isInlineSpecified(); diff --git a/test/CodeGenCXX/debug-info-same-line.cpp b/test/CodeGenCXX/debug-info-same-line.cpp index 05b426e25c..c6216b3ff8 100644 --- a/test/CodeGenCXX/debug-info-same-line.cpp +++ b/test/CodeGenCXX/debug-info-same-line.cpp @@ -6,118 +6,59 @@ #define INLINE inline __attribute__((always_inline)) -INLINE int -product (int x, int y) -{ - int result = x * y; - return result; -} - -INLINE int -sum (int a, int b) -{ - int result = a + b; - return result; -} +int i; -int -strange_max (int m, int n) -{ - if (m > n) - return m; - else if (n > m) - return n; - else - return 0; +INLINE void sum(int a, int b) { + i = a + b; } -int -foo (int i, int j) -{ - if (strange_max (i, j) == i) - return product (i, j); - else if (strange_max (i, j) == j) - return sum (i, j); - else - return product (sum (i, i), sum (j, j)); +void noinline(int x, int y) { + i = x + y; } -int -main(int argc, char const *argv[]) -{ - - int array[3]; - int n; +#define CALLS sum(9, 10), sum(11, 12) - array[0] = foo (1238, 78392); - array[1] = foo (379265, 23674); - array[2] = foo (872934, 234); - - n = strange_max(array[0], strange_max(array[1], array[2])); - - return n & 0xf; +inline void inlsum(int t, int u) { + i = t + u; } -// CHECK: define {{.*}} @_Z3fooii -// i -// CHECK: call void @llvm.dbg.declare -// j -// CHECK: call void @llvm.dbg.declare -// x -// CHECK: call void @llvm.dbg.declare -// y -// CHECK: call void @llvm.dbg.declare -// result -// CHECK: call void @llvm.dbg.declare - -// CHECK: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[A_MD:[0-9]+]]), !dbg ![[A_DI:[0-9]+]] -// CHECK: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[B_MD:[0-9]+]]), !dbg ![[B_DI:[0-9]+]] -// result -// CHECK: call void @llvm.dbg.declare - -// We want to see a distinct !dbg node. -// CHECK-NOT: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[A_MD]]), !dbg ![[A_DI]] -// CHECK: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[A_MD]]), !dbg !{{.*}} -// CHECK-NOT: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[B_MD]]), !dbg ![[B_DI]] -// CHECK: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[B_MD]]), !dbg !{{.*}} -// result -// CHECK: call void @llvm.dbg.declare - -// We want to see a distinct !dbg node. -// CHECK-NOT: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[A_MD]]), !dbg ![[A_DI]] -// CHECK: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[A_MD]]), !dbg !{{.*}} -// CHECK-NOT: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[B_MD]]), !dbg ![[B_DI]] -// CHECK: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[B_MD]]), !dbg !{{.*}} -// result -// CHECK: call void @llvm.dbg.declare - -// Again: we want to see a distinct !dbg node. -// CHECK: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[X_MD:[0-9]+]]), !dbg ![[X_DI:[0-9]+]] -// CHECK: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[Y_MD:[0-9]+]]), !dbg ![[Y_DI:[0-9]+]] -// result -// CHECK: call void @llvm.dbg.declare - - -// CHECK: define {{.*}} @main -// CHECK: call {{.*}} @_Z3fooii -// CHECK: call {{.*}} @_Z3fooii -// CHECK: call {{.*}} @_Z3fooii -// CHECK: store -// CHECK: getelementptr -// We want to see the same !dbg node for non-inlined functions. -// Needed for GDB compatibility. -// CHECK: load {{.*}} !dbg ![[DBG:.*]] -// CHECK: load {{.*}} !dbg ![[DBG]] -// CHECK: load {{.*}} !dbg ![[DBG]] -// CHECK: call {{.*}} @_Z11strange_maxii(i32 {{.*}}, i32 {{.*}}), !dbg ![[DBG]] -// CHECK: call {{.*}} @_Z11strange_maxii(i32 {{.*}}, i32 {{.*}}), !dbg ![[DBG]] - +int main() { + sum(1, 2), sum(3, 4); + noinline(5, 6), noinline(7, 8); + CALLS; + inlsum(13, 14), inlsum(15, 16); +} -// Verify that product() has its own inlined_at location at column 15. -// CHECK-DAG: ![[A_MD]] = metadata{{.*}}[ DW_TAG_arg_variable ] [a] -// CHECK-DAG: ![[B_MD]] = metadata{{.*}}[ DW_TAG_arg_variable ] [b] -// CHECK-DAG: ![[X_MD]] = metadata{{.*}}[ DW_TAG_arg_variable ] [x] -// CHECK-DAG: ![[Y_MD]] = metadata{{.*}}[ DW_TAG_arg_variable ] [y] -// CHECK-DAG: ![[X_DI]] = metadata !{i32 {{[0-9]+}}, i32 {{[0-9]+}}, metadata !{{[0-9]+}}, metadata ![[PRODUCT:[0-9]+]]} -// CHECK-DAG: [[PRODUCT]] = metadata !{i32 {{.*}}, i32 16, metadata !{{.*}}, null} -// CHECK-DAG: ![[Y_DI]] = metadata !{i32 {{[0-9]+}}, i32 {{[0-9]+}}, metadata !{{[0-9]+}}, metadata ![[PRODUCT]]} +// CHECK-LABEL: @main +// CHECK: = add {{.*}} !dbg [[FIRST_INLINE:![0-9]*]] +// CHECK: = add {{.*}} !dbg [[SECOND_INLINE:![0-9]*]] + +// Check that we don't give column information (and thus end up with distinct +// line entries) for two non-inlined calls on the same line. +// CHECK: call {{.*}}noinline{{.*}}(i32 5, i32 6), !dbg [[NOINLINE:![0-9]*]] +// CHECK: call {{.*}}noinline{{.*}}(i32 7, i32 8), !dbg [[NOINLINE]] + +// FIXME: These should be separate locations but because the two calls have the +// same line /and/ column, they get coalesced into a single inlined call by +// accident. We need discriminators or some other changes to LLVM to cope with +// this. (this is, unfortunately, an LLVM test disguised as a Clang test - since +// inlining is forced to happen here). It's possible this could be fixed in +// Clang, but I doubt it'll be the right place for the fix. +// CHECK: = add {{.*}} !dbg [[FIRST_MACRO_INLINE:![0-9]*]] +// CHECK: = add {{.*}} !dbg [[FIRST_MACRO_INLINE]] + +// Even if the functions are marked inline but do not get inlined, they +// shouldn't use column information, and thus should be at the same debug +// location. +// CHECK: call {{.*}}inlsum{{.*}}(i32 13, i32 14), !dbg [[INL_FIRST:![0-9]*]] +// CHECK: call {{.*}}inlsum{{.*}}(i32 15, i32 16), !dbg [[INL_SECOND:![0-9]*]] + +// [[FIRST_INLINE]] = +// [[SECOND_INLINE]] = + +// FIXME: These should be the same location since the functions appear on the +// same line and were not inlined - they needlessly have column information +// intended to disambiguate inlined calls, which is going to confuse GDB as it +// doesn't cope well with column information. +// [[INL_FIRST]] = +// [[INL_SECOND]] =