[llvm-bugs] [Bug 40313] New: With __PRETTY_FUNCTION__, dereferencing same pointer produces different results at compile time vs. runtime

via llvm-bugs llvm-bugs at lists.llvm.org
Mon Jan 14 19:32:49 PST 2019


https://bugs.llvm.org/show_bug.cgi?id=40313

            Bug ID: 40313
           Summary: With __PRETTY_FUNCTION__, dereferencing same pointer
                    produces different results at compile time vs. runtime
           Product: clang
           Version: trunk
          Hardware: PC
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: C++
          Assignee: unassignedclangbugs at nondot.org
          Reporter: comexk at gmail.com
                CC: blitzrakete at gmail.com, dgregor at apple.com,
                    erik.pilkington at gmail.com, llvm-bugs at lists.llvm.org,
                    richard-llvm at metafoo.co.uk

The below example outputs:

string:'top level' first_eight:'Ret get_'

which indicates that "str" is equal to "Ret get_foo()" when dereferenced at
compile time, but equal to "top level" when dereferenced at runtime.

The bug seems to be in the methods ConstantLValueEmitter::VisitPredefinedExpr
and CodeGenFunction::EmitPredefinedLValue.  The code seems to assume that the
current CodeGenFunction corresponds to the function the PredefinedExpr is
originally from, which is no longer guaranteed when constexpr is used.

ConstantLValueEmitter::VisitPredefinedExpr checks whether there is a current
CodeGenFunction, and calls CodeGenFunction::EmitPredefinedLValue if so.  In the
below example, the constexpr variable is instantiated at a global level, so
there is no current CodeGenFunction.  In this case,
ConstantLValueEmitter::VisitPredefinedExpr hardcodes "top level" as the string
literal.  This is strange, since the string literal was computed earlier on and
is included in the PredefinedExpr object as the return value of
getFunctionName().

If the constexpr variable declaration is moved to within a function, it appears
to return the right string but, as far as I can tell, is subtly incorrect. 
CodeGenFunction::EmitPredefinedLValue normally calls getFunctionName() for the
contents of the string literal, but uses the current CodeGenFunction, combined
with the type of predefined expr, to name the *symbol* containing that literal.
 This name is supposed to uniquely identify the string contents, which it does
if the current CodeGenFunction is the function the PredefinedExpr was from
(whose name was used to compute the string contents), but not if it's some
random other function.


#include <stdio.h>
#include <string.h>

struct Ret {
    const char *string;
    char first_eight[8];
    char zero;
};

constexpr Ret get_foo() {
    constexpr const char *str = __PRETTY_FUNCTION__;
    return {
        str,
        {str[0], str[1], str[2], str[3],
         str[4], str[5], str[6], str[7]},
        '\0'
    };  
}
constexpr Ret foo = get_foo();

int main() {
    printf("string:'%s' first_eight:'%s'\n", foo.string, foo.first_eight);
}

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20190115/864faaa0/attachment.html>


More information about the llvm-bugs mailing list