Skip to content

improve trivial_abi documentation to better describe the cases where it should not be used #36667

@Quuxplusone

Description

@Quuxplusone
Bugzilla Link 37319
Version trunk
OS All
CC @dwblaikie,@efriedma-quic,@zygoloid

Extended Description

#include <assert.h>
#include <stdint.h>

#define TRIVIAL_ABI __attribute__((trivial_abi))

template<class T>
class TRIVIAL_ABI trivial_offset_ptr {
    intptr_t value_;
public:
    trivial_offset_ptr(T *p) : value_((const char*)p - (const char*)this) {}
    trivial_offset_ptr(const trivial_offset_ptr& rhs) : value_((const char*)rhs.get() - (const char*)this) {}
    T *get() const { return (T *)((const char *)this + value_); }
    trivial_offset_ptr& operator=(const trivial_offset_ptr& rhs) {
        value_ = ((const char*)rhs.get() - (const char*)this);
        return *this;
    }
    trivial_offset_ptr& operator+=(int diff) {
        value_ += (diff * sizeof (T));
        return *this;
    }
};

trivial_offset_ptr<int>
incr(trivial_offset_ptr<int> p) {
    p += 1;
    return p;
}

int main() {
    int a[10];
    trivial_offset_ptr<int> op = &a[4];
    trivial_offset_ptr<int> top = &a[4];
    top = incr(top);
    assert(top.get() == &a[5]);
}
clang++ -std=c++17 -O1 test.cc -o a.out
./a.out  # works great!

clang++ -std=c++17 -O2 test.cc -o a.out
./a.out

Assertion failed: (top.get() == &a[5]), function main, file test.cc, line 34.
Abort trap: 6

====

This is super sneaky UB-ful code in theory, I'm sure, but IMHO Clang is still doing something not-conservative-enough here. Especially, notice that if you remove the unused local variable op from main, the assertion will pass. Put the unused variable back, and the assertion will fail.

Documentation for [[trivial_abi]] is here. It does not mention any caveats about "don't implement offset_ptr with this attribute." I would grudgingly accept that outcome if it were proposed (but I'd rather the code Just Work).
https://clang.llvm.org/docs/AttributeReference.html#trivial-abi-clang-trivial-abi

P.S. I am aware that [[trivial_abi]] is super new, and I love it, and I don't mean to be harsh at all in this first corner-case bug filed against it. :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugzillaIssues migrated from bugzillaclangClang issues not falling into any other categorydocumentation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions