Skip to content

Commit

Permalink
[clang][Interp] Don't add 'in call to' diagnostics for builtin frames
Browse files Browse the repository at this point in the history
  • Loading branch information
tbaederr committed Apr 16, 2024
1 parent ac6b4c6 commit 09e7d75
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 18 deletions.
7 changes: 7 additions & 0 deletions clang/lib/AST/Interp/InterpFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,13 @@ void print(llvm::raw_ostream &OS, const Pointer &P, ASTContext &Ctx,
}

void InterpFrame::describe(llvm::raw_ostream &OS) const {
// We create frames for builtin functions as well, but we can't reliably
// diagnose them. The 'in call to' diagnostics for them add no value to the
// user _and_ it doesn't generally work since the argument types don't always
// match the function prototype. Just ignore them.
if (const auto *F = getFunction(); F && F->isBuiltin())
return;

const FunctionDecl *F = getCallee();
if (const auto *M = dyn_cast<CXXMethodDecl>(F);
M && M->isInstance() && !isa<CXXConstructorDecl>(F)) {
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/AST/Interp/State.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ void State::addCallStack(unsigned Limit) {
SmallString<128> Buffer;
llvm::raw_svector_ostream Out(Buffer);
F->describe(Out);
addDiag(CallRange.getBegin(), diag::note_constexpr_call_here)
<< Out.str() << CallRange;
if (!Buffer.empty())
addDiag(CallRange.getBegin(), diag::note_constexpr_call_here)
<< Out.str() << CallRange;
}
}
24 changes: 8 additions & 16 deletions clang/test/AST/Interp/builtin-functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,13 @@ namespace strcmp {
static_assert(__builtin_strcmp("abab", "abab\0banana") == 0, "");
static_assert(__builtin_strcmp("abab\0banana", "abab\0canada") == 0, "");
static_assert(__builtin_strcmp(0, "abab") == 0, ""); // both-error {{not an integral constant}} \
// both-note {{dereferenced null}} \
// expected-note {{in call to}}
// both-note {{dereferenced null}}
static_assert(__builtin_strcmp("abab", 0) == 0, ""); // both-error {{not an integral constant}} \
// both-note {{dereferenced null}} \
// expected-note {{in call to}}
// both-note {{dereferenced null}}

static_assert(__builtin_strcmp(kFoobar, kFoobazfoobar) == -1, "");
static_assert(__builtin_strcmp(kFoobar, kFoobazfoobar + 6) == 0, ""); // both-error {{not an integral constant}} \
// both-note {{dereferenced one-past-the-end}} \
// expected-note {{in call to}}
// both-note {{dereferenced one-past-the-end}}

/// Used to assert because we're passing a dummy pointer to
/// __builtin_strcmp() when evaluating the return statement.
Expand Down Expand Up @@ -72,14 +69,11 @@ constexpr const char *a = "foo\0quux";
static_assert(check(c), "");

constexpr int over1 = __builtin_strlen(a + 9); // both-error {{constant expression}} \
// both-note {{one-past-the-end}} \
// expected-note {{in call to}}
// both-note {{one-past-the-end}}
constexpr int over2 = __builtin_strlen(b + 9); // both-error {{constant expression}} \
// both-note {{one-past-the-end}} \
// expected-note {{in call to}}
// both-note {{one-past-the-end}}
constexpr int over3 = __builtin_strlen(c + 9); // both-error {{constant expression}} \
// both-note {{one-past-the-end}} \
// expected-note {{in call to}}
// both-note {{one-past-the-end}}

constexpr int under1 = __builtin_strlen(a - 1); // both-error {{constant expression}} \
// both-note {{cannot refer to element -1}}
Expand All @@ -90,8 +84,7 @@ constexpr const char *a = "foo\0quux";

constexpr char d[] = { 'f', 'o', 'o' }; // no nul terminator.
constexpr int bad = __builtin_strlen(d); // both-error {{constant expression}} \
// both-note {{one-past-the-end}} \
// expected-note {{in call to}}
// both-note {{one-past-the-end}}
}

namespace nan {
Expand All @@ -114,8 +107,7 @@ namespace nan {
/// FIXME: Current interpreter misses diagnostics.
constexpr char f2[] = {'0', 'x', 'A', 'E'}; /// No trailing 0 byte.
constexpr double NaN7 = __builtin_nan(f2); // both-error {{must be initialized by a constant expression}} \
// expected-note {{read of dereferenced one-past-the-end pointer}} \
// expected-note {{in call to}}
// expected-note {{read of dereferenced one-past-the-end pointer}}
static_assert(!__builtin_issignaling(__builtin_nan("")), "");
static_assert(__builtin_issignaling(__builtin_nans("")), "");
}
Expand Down

0 comments on commit 09e7d75

Please sign in to comment.