May be This small example will help you understand nontrivial function in the context of [basic.def.odr]/3
struct C {
int l;
constexpr C(int _l) : l(_l) { }
constexpr C(const C&c) : q(c.l* 2) { }
};
int main(void) {
constexpr C c(42);
constexpr int m= c.l;
struct K{
int foo() { return c.l; }
} l;
return l.foo();
}
If You look at the follwowing line in standard
applying the lvalue-to-rvalue conversion (4.1) to x yields a constant expression (5.19) that does not invoke any nontrivial functions
Here c satisfies the requirements for appearing in a constant expression,
but applying the lvalue-to-rvalue conversion to a invokes a
non-trivial function.
Why It invokes a non-trivial function?
When an lvalue-to-rvalue conversion occurs in an unevaluated operand or a subexpression thereof the value contained in the referenced object is not accessed. Otherwise, if the glvalue has a class type, the conversion copy-initializes a temporary of type T from the glvalue and the result of the conversion is a prvalue for the temporary
So a prvalue is created using the copy constructor of class C and since Copy constructor is user Declared, It is non-Trivial and Hence c is not ODR-used here
A copy/move assignment operator for class X is trivial if it is not user-provided, its parameter-type-list is equivalent to the parameter-type-list of an implicit declaration
I hope this example clarifies your doubt