Bug 106563 - [12/13 Regression] d: undefined reference to pragma(inline) symbol
Summary: [12/13 Regression] d: undefined reference to pragma(inline) symbol
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: d (show other bugs)
Version: 12.0
: P4 normal
Target Milestone: 12.2
Assignee: Iain Buclaw
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-08-08 19:43 UTC by Iain Buclaw
Modified: 2022-08-09 12:43 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work: 11.1.0
Known to fail: 12.1.0
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Iain Buclaw 2022-08-08 19:43:42 UTC
Compiled with `gdc test.d` results in:
/usr/bin/ld: /tmp/ccxf3O8c.o: in function `stdx.math.nextPow2!(ulong).nextPow2(const(ulong))':
test.d:(.text+0x6d): undefined reference to `stdx.math.powIntegralImpl!(const(ulong)).powIntegralImpl(const(ulong))'
collect2: error: ld returned 1 exit status

Because the function is pragma(inline), it should receive automatic codegen during the front-end -> GCC tree lowering pass.

---
module stdx.math;

T nextPow2(T)(const T val)
{
    return powIntegralImpl(val);
}

pragma(inline, true)
T powIntegralImpl(T)(T)
{
    return 1;
}
---
module stdx.regex;
import stdx.uni;

struct CharMatcher
{
    typeof(MultiArray!().length) trie;
}
---
module stdx.uni;

struct MultiArray()
{
    @property length()
    {
        return spaceFor!0();
    }
}

size_t spaceFor(size_t bits)()
{
    import stdx.math;
    return nextPow2(bits);
}
---
module test;
import stdx.math;
import stdx.regex;

void requireSize()(size_t size)
{
    nextPow2(size);
}

void main()
{
    requireSize(0);
}
Comment 1 Iain Buclaw 2022-08-08 19:45:05 UTC
Well, not really a regression, but it rears its ugly head in gdc-12 because nextPow2() now gets instantiated in the `test' module, whereas previously it didn't.
Comment 2 GCC Commits 2022-08-09 12:41:47 UTC
The master branch has been updated by Iain Buclaw <ibuclaw@gcc.gnu.org>:

https://gcc.gnu.org/g:04284176d549ff2565406406a6d53ab4ba8e507d

commit r13-2002-g04284176d549ff2565406406a6d53ab4ba8e507d
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date:   Tue Aug 9 12:48:14 2022 +0200

    d: Fix undefined reference to pragma(inline) symbol (PR106563)
    
    Functions that are declared `pragma(inline)' should be treated as if
    they are defined in every translation unit they are referenced from,
    regardless of visibility protection.  Ensure they always get
    DECL_ONE_ONLY linkage, and start emitting them into other modules that
    import them.
    
            PR d/106563
    
    gcc/d/ChangeLog:
    
            * decl.cc (DeclVisitor::visit (FuncDeclaration *)): Set semanticRun
            before generating its symbol.
            (function_defined_in_root_p): New function.
            (function_needs_inline_definition_p): New function.
            (maybe_build_decl_tree): New function.
            (get_symbol_decl): Call maybe_build_decl_tree before returning symbol.
            (start_function): Use function_defined_in_root_p instead of inline
            test for locally defined symbols.
            (set_linkage_for_decl): Check for inline functions before private or
            protected symbols.
    
    gcc/testsuite/ChangeLog:
    
            * gdc.dg/torture/torture.exp (srcdir): New proc.
            * gdc.dg/torture/imports/pr106563math.d: New test.
            * gdc.dg/torture/imports/pr106563regex.d: New test.
            * gdc.dg/torture/imports/pr106563uni.d: New test.
            * gdc.dg/torture/pr106563.d: New test.
Comment 3 GCC Commits 2022-08-09 12:42:29 UTC
The releases/gcc-12 branch has been updated by Iain Buclaw <ibuclaw@gcc.gnu.org>:

https://gcc.gnu.org/g:79a86a608691621659b3ce3a24a72aeea4054668

commit r12-8673-g79a86a608691621659b3ce3a24a72aeea4054668
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date:   Tue Aug 9 12:48:14 2022 +0200

    d: Fix undefined reference to pragma(inline) symbol (PR106563)
    
    Functions that are declared `pragma(inline)' should be treated as if
    they are defined in every translation unit they are referenced from,
    regardless of visibility protection.  Ensure they always get
    DECL_ONE_ONLY linkage, and start emitting them into other modules that
    import them.
    
            PR d/106563
    
    gcc/d/ChangeLog:
    
            * decl.cc (DeclVisitor::visit (FuncDeclaration *)): Set semanticRun
            before generating its symbol.
            (function_defined_in_root_p): New function.
            (function_needs_inline_definition_p): New function.
            (maybe_build_decl_tree): New function.
            (get_symbol_decl): Call maybe_build_decl_tree before returning symbol.
            (start_function): Use function_defined_in_root_p instead of inline
            test for locally defined symbols.
            (set_linkage_for_decl): Check for inline functions before private or
            protected symbols.
    
    gcc/testsuite/ChangeLog:
    
            * gdc.dg/torture/torture.exp (srcdir): New proc.
            * gdc.dg/torture/imports/pr106563math.d: New test.
            * gdc.dg/torture/imports/pr106563regex.d: New test.
            * gdc.dg/torture/imports/pr106563uni.d: New test.
            * gdc.dg/torture/pr106563.d: New test.
    
    (cherry picked from commit 04284176d549ff2565406406a6d53ab4ba8e507d)
Comment 4 Iain Buclaw 2022-08-09 12:43:28 UTC
Fix committed.