[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