Same AST for is_same<char, int>::value and is_same<char, long>::value

(Resending from my personal email address)

Comparing the getQualifier()->getAsRecordDecl()s of the two DeclRefExprs should do it I think (untested). Careful though, NNS::getAsRecordDecl() crashes instead of returning null if the qualifier is e.g. a namespace, check its implem for the permissible kinds (or maybe better to add a getAsRecordDeclUnsafe() method).

Thanks for your response David!

Actually, clang-tidy does something similar in the misc-redundant-expression check.

areEquivalentNameSpecifier(

cast(Left)->getQualifier(),

cast(Right)->getQualifier());

static bool areEquivalentNameSpecifier(const NestedNameSpecifier *Left,

const NestedNameSpecifier *Right) {

llvm::FoldingSetNodeID LeftID, RightID;

Left->Profile(LeftID);

Right->Profile(RightID);

return LeftID == RightID;

}

But when I try to create a positive test case I fail.

At line 7 in the next example, I don’t get a warning.

It is because the folding set nodes (LeftID and RightID) are different.

Just like the pointer values of Left and Right.

I’m surprised about this, since I’m referring to the very same variable, thus I would expect the same pointer values.

When I dump nested name specifiers I get the same string: “my_trait::”

1 template struct boolean_value {

2 static constexpr bool value = V;

3 };

4 template struct my_trait : boolean_value {};

5 bool respect_nested_name_specifiers(bool sink) {

6 sink = my_trait::value || my_trait::value; // no-warning, awesome

7 sink = my_trait::value || my_trait::value; // no warning for this either :frowning:

8 return sink;

9 }

How is it possible to have different NestedNameSpecifier pointers describing the same thing?

Am I missing something?

Thanks,

Balázs

Thanks for your response David!

Actually, clang-tidy does something similar in the misc-redundant-expression check.

areEquivalentNameSpecifier(

cast(Left)->getQualifier(),

cast(Right)->getQualifier());

static bool areEquivalentNameSpecifier(const NestedNameSpecifier *Left,

const NestedNameSpecifier *Right) {

llvm::FoldingSetNodeID LeftID, RightID;

Left->Profile(LeftID);

Right->Profile(RightID);

return LeftID == RightID;

}

But when I try to create a positive test case I fail.

At line 7 in the next example, I don’t get a warning.

It is because the folding set nodes (LeftID and RightID) are different.

Just like the pointer values of Left and Right.

I’m surprised about this, since I’m referring to the very same variable, thus I would expect the same pointer values.

When I dump nested name specifiers I get the same string: “my_trait::”

1 template struct boolean_value {

2 static constexpr bool value = V;

3 };

4 template struct my_trait : boolean_value {};

5 bool respect_nested_name_specifiers(bool sink) {

6 sink = my_trait::value || my_trait::value; // no-warning, awesome

7 sink = my_trait::value || my_trait::value; // no warning for this either :frowning:

8 return sink;

9 }

How is it possible to have different NestedNameSpecifier pointers describing the same thing?

Am I missing something?

Thanks David, it seems to work now.
I’ll run it on a few projects to see if it crashes or something.
Stay tuned for the patch!