Re: [cfe-users] [cfe-dev] Warnings for implicit constructors and wrong usage of auto

2018-05-15 Thread Richard Smith via cfe-users
On 15 May 2018 at 16:01, John McCall via cfe-dev 
wrote:

> On May 15, 2018, at 6:05 PM, George Karpenkov via cfe-dev <
> cfe-...@lists.llvm.org> wrote:
>
> +cfe-dev
>
> Hi Andrea,
>
> I think you might get more luck asking on the cfe-dev mailing list.
>
>
> George
>
> On May 15, 2018, at 1:15 PM, Andrea Arteaga via cfe-users <
> cfe-users@lists.llvm.org> wrote:
>
> Dear all,
> Recently, my team suffered from a bug due to a double bad usage of C++.
>
> We have a function returning a reference to an object:
>
> Object& GetObject();
>
> Sometimes we use this function like this:
>
> auto obj = GetObject();
>
> This triggers a copy of the object, which we really don't mean. The two
> problems are:
> 1. Object does not delete the copy constructor, nor does it declare one.
> We have a policy of never using implicitly-declared constructors, we either
> use `=delete` or `=default`. Nevertheless we missed this class.
>
>
> Implicitly-defined copy constructors are ubiquitous in idiomatic C++.
> Maybe that's not true in your project, but still, this seems too
> special-case for the compiler.  Maybe a linter that has a more
> sophisticated model of what code is yours vs. the standard library.
>
> 2. A reference is demoted to a rvalue due to the usage of `auto` instead
> of `auto&`.
>
>
> This is a more reasonable thing to try to warn about.  I have two concerns:
>   - I don't know a reasonable way to suppress the warning if you really do
> want to load from the l-value.
>   - I have a non-specific worry that it'll disrupt some important idiom
> that I'm just not thinking of.
>

How about:

  vector v = get_vector();
  auto x = v.front();

or, worse:

  auto y = get_vector().front();

But those are concerns that we could explore during iterative design and
> implementation.
>
> John.
>
> ___
> cfe-dev mailing list
> cfe-...@lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
>
___
cfe-users mailing list
cfe-users@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] problem with `candidate template ignored: invalid explicitly-specified argument'

2018-11-07 Thread Richard Smith via cfe-users
The rule for determining when a base class function declaration introduced
by a using-declaartion is hidden by a derived class function declaration
does not take the template parameter list into account:
http://eel.is/c++draft/namespace.udecl#15.sentence-1

So clang's behaviour is conforming and gcc's behaviour is not. At the very
least, though, we should issue a warning for the using declaration, because
this is a surprising rule.

On Wed, 7 Nov 2018, 08:28 Werner LEMBERG 
> > Sure, that'd be great - http://bugs.llvm.org
>
> Done:
>
>   https://bugs.llvm.org/show_bug.cgi?id=39581
>
>
> Werner
>
___
cfe-users mailing list
cfe-users@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] problem with `candidate template ignored: invalid explicitly-specified argument'

2018-11-07 Thread Richard Smith via cfe-users
On Wed, 7 Nov 2018 at 11:44, Jan Korous  wrote:

>
> > On Nov 7, 2018, at 7:03 PM, Werner LEMBERG via cfe-users <
> cfe-users@lists.llvm.org> wrote:
> >
> >
> >> The rule for determining when a base class function declaration
> >> introduced by a using-declaration is hidden by a derived class
> >> function declaration does not take the template parameter list into
> >> account: http://eel.is/c++draft/namespace.udecl#15.sentence-1
> >
> > Our main lilypond developer disagrees.  He writes:
> >
> >  This link states:
> >
> >When a using-declarator brings declarations from a base class into
> >a derived class, member functions and member function templates in
> >the derived class override and/or hide member functions and member
> >function templates with the same name, parameter-type-list,
> >cv-qualification, and ref-qualifier (if any) in a base class
> >(rather than conflicting).
> >
> >  The parameter-type-list is a different one in this example since
> >  they contain a different member function pointer type.  Which is the
> >  reason we need the whole hooplahoop in the first place.
> >
>
> Isn’t it template-parameter-list that is different rather than
> parameter-type-list?
>
> http://eel.is/c++draft/dcl.fct#def:parameter-type-list
> http://eel.is/c++draft/temp#nt:template-parameter-list


Yes. The pieces are these:

template
   // template-parameter-list
void f
  (int N) // parameter-type-list

Both base and derived function template have a parameter-type-list of (). :(

> For context, the whole lilypond thread starts at
> >
> >  https://lists.gnu.org/archive/html/lilypond-devel/2018-11/msg00019.html
> >
> >
> >Werner
> > ___
> > cfe-users mailing list
> > cfe-users@lists.llvm.org
> > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
>
>
___
cfe-users mailing list
cfe-users@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] How to have clang ignore gch directories?

2019-04-25 Thread Richard Smith via cfe-users
On Tue, 23 Apr 2019 at 12:06, Paul Smith via cfe-users
 wrote:
>
> How can I get clang to stop caring about gch directories for
> precompiled headers that were created by GCC?
>
> Currently my main build uses GCC and it generates .gch directories:
>
>   $ ls -1d foo_pch*
>   foo_pch.h
>   foo_pch.h.gch/
>
> When I compile my code using GCC, it works fine:
>
>   $ g++ ... -Winvalid-pch --include=foo_pch.h ...
>
> But then if I try to use tools based on clang with exactly the same
> arguments, it throws an error (with or without -Winvalid-pch):
>
>   $ clang++ ... --include=foo_pch.h ...
>   error: no suitable precompiled header file found in directory
>   './foo_pch.h.gch'
>   1 error generated.
>
> Note I'm really not using clang++, I'm using a tool linked with libLLVM
> which parses the code, but I get the same behavior there.
>
> Using strace I can see clang first look for .pch then .pth (neither of
> which exist, which is fine), and finally .gch.  Apparently clang cannot
> parse the GCC-generated precompiled header file.  I don't care if clang
> can't read those files, I just want it to include the .h file.
>
> How can I tell clang to just ignore the GCC-specific precompiled
> headers, or equivalently ignore precompiled headers altogether?  I
> can't delete the gch directories because I need them for my build. I've
> read through the clang docs and can't find any likely-looking options.
>
> It's really frustrating when clang tries to appropriate GCC-specific
> options and configurations when it's not actually compatible with them.
> It makes modern multi-compiler development so unnecessarily difficult.

Sorry about that. Clang is trying to be a transparent drop-in
replacement for build systems that are designed for GCC, and that
means that -include needs to automatically pick up a corresponding
.pch / .gch file if a prior build step put one there. Unfortunately we
don't do any validation to check whether that's Clang's file or one
generated by GCC at that layer :(

You can work around this by using "-Xclang -include -Xclang foo_pch.h"
instead of "-include foo_pch.h"; that will bypass the driver logic
that tries to convert -include to -include-pch.

Also, -include=foo_pch.h won't do what you think: in GCC (and in
Clang, because we usually follow GCC conventions even when they're
weird), that will include a file named "=foo_pch.h". (The space
between -include and the filename is optional, and there is no
optional equals, so if you put one in it ends up as part of the
argument value. This is the same behavior as for -I etc.)
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] Fwd: Re: [llvm-dev] Overriding macro values defined in source code

2019-05-08 Thread Richard Smith via cfe-users
On Mon, 6 May 2019 at 23:09, Sudhindra kulkarni via cfe-users
 wrote:
>
>
> -- Forwarded message --
> From: "Tim Northover" 
> Date: May 1, 2019 3:48 PM
> Subject: Re: [llvm-dev] Overriding macro values defined in source code
> To: "Sudhindra kulkarni" 
> Cc: "LLVM Developers Mailing List" 
>
> On Tue, 30 Apr 2019 at 22:28, Sudhindra kulkarni via llvm-dev
>  wrote:
> > Is it possible to override the value of AVAL through the -D option?
> > For eg is it possible to set the value of AVAL to 2 through -D in clang ?
>
> This is more a question for the cfe-users list, but as far as I know
> there's no way to prevent redefinitions in source files.
>
> Cheers.
>
> Tim.
>
> Hi Team,
>  Consider the below C code,
> #define AVAL 5
> void func()
> {
> int a=5;
> if(a==AVAL)
> {
> //Do something
> }
> else
> {
> //Do something else
> }
>
> }
> My question is
> Is it possible to override the value of AVAL through the -D option?
> For eg is it possible to set the value of AVAL to 2 through -D in clang so 
> that the else part executes?
> Also apart from -D option we are also open to other ways of achieving this

The normal approach is to change the source to something like

#ifndef AVAL
#define AVAL 5
#endif

> Thanks in advance
> ___
> cfe-users mailing list
> cfe-users@lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] Fwd: Re: [llvm-dev] Overriding macro values defined in source code

2019-05-10 Thread Richard Smith via cfe-users
On Thu, 9 May 2019 at 22:47, Sudhindra kulkarni
 wrote:
>
> Thanks Richard for the answer.
>
> I have another question regarding the include(-I) option.
>
> If we have a c file called cfile.c and a header file called header.h both in 
> the same directory say (dir x).  cfile.c includes header.h as shown below
> #include "header.h"
> And if in some other directory say (dir y)we have another header file with 
> the same name(header.h) but with a different content then when I try to 
> generate the preprocessed file using the below command,
> clang.exe -E path of cfile.c -I path of dir y
> The header.h present in the directory dir x is getting considered even though 
> -I points to dir y.
>
> Is this the intended behavior that the current directory is searched first 
> for the header files irrespective of the directory provided against the -I 
> option.
> If not how to make clang consider only the directories provided against the 
> -I option and not the current directory.

I think the only way to suppress the search in the directory of the
file containing the #include is with the -I- (dash, capital i, dash)
option. (That option also has other effects on the #include path, and
it matters where you place it relative to other -I flags.) It'd
probably be worth adding a dedicated flag for just the "don't look in
the directory containing the file" effect.

> Thanks in advance
>
>
>
>
>
>
>
> On May 9, 2019 5:01 AM, "Richard Smith"  wrote:
>
> On Mon, 6 May 2019 at 23:09, Sudhindra kulkarni via cfe-users
>  wrote:
> >
> >
> > -- Forwarded message --
> > From: "Tim Northover" 
> > Date: May 1, 2019 3:48 PM
> > Subject: Re: [llvm-dev] Overriding macro values defined in source code
> > To: "Sudhindra kulkarni" 
> > Cc: "LLVM Developers Mailing List" 
> >
> > On Tue, 30 Apr 2019 at 22:28, Sudhindra kulkarni via llvm-dev
> >  wrote:
> > > Is it possible to override the value of AVAL through the -D option?
> > > For eg is it possible to set the value of AVAL to 2 through -D in clang ?
> >
> > This is more a question for the cfe-users list, but as far as I know
> > there's no way to prevent redefinitions in source files.
> >
> > Cheers.
> >
> > Tim.
> >
> > Hi Team,
> >  Consider the below C code,
> > #define AVAL 5
> > void func()
> > {
> > int a=5;
> > if(a==AVAL)
> > {
> > //Do something
> > }
> > else
> > {
> > //Do something else
> > }
> >
> > }
> > My question is
> > Is it possible to override the value of AVAL through the -D option?
> > For eg is it possible to set the value of AVAL to 2 through -D in clang so 
> > that the else part executes?
> > Also apart from -D option we are also open to other ways of achieving this
>
> The normal approach is to change the source to something like
>
> #ifndef AVAL
> #define AVAL 5
> #endif
>
> > Thanks in advance
> > ___
> > cfe-users mailing list
> > cfe-users@lists.llvm.org
> > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
>
>
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] Getting underlying type for `using typename` declaration

2019-07-22 Thread Richard Smith via cfe-users
On Wed, 17 Jul 2019 at 23:20, Victor “LOST” Milovanov via cfe-users <
cfe-users@lists.llvm.org> wrote:

> Hi CFE users!
>
>
>
> I am trying to get a `QualType` instance from
> `UnresolvedUsingTypenameDecl`. Unlike `TypeAliasDecl`
> `UnresolvedUsingTypenameDecl` does not have a `getUnderlyingType` method.
>
>
>
> I could not find a way to construct one from the `DeclarationNameInfo`
> (`getNameInfo`) and `NestedNameSpecifier` (`getQualifier`).
>

You could build a suitable QualType by calling
Sema::CheckTypenameType(ETK_Typename, U->getTypenameLoc(),
U->getQualifierLoc(), U->getIdentifier(), U->getLocation()).


> The library I am working on already supports type aliases, and I was
> hoping I could treat `using typename` declarations in a similar way. Not
> sure if it is the right way though.
>
>
>
> Regards,
>
> Victor
> ___
> cfe-users mailing list
> cfe-users@lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
>
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] How to get code for a function template specialization

2019-08-04 Thread Richard Smith via cfe-users
On Fri, 2 Aug 2019 at 15:05, Romulo via cfe-users 
wrote:

> Hello there, thanks for your time reading this :)
>
> I am trying to extract the code for a specialized template function, but I
> have no idea on how to proceed. I know I can use SourceManager to get the
> original 'pure template' code but I don't know how to access the
> specialized functions (the SourceLocation for them points to the original
> function in the AST). My idea is to allow users to write some sugar code
> like:
>
> template 
> T myAdd(T x, T y) {
>   return x + y;
> }
>
> myAdd< double >(5.5, 3.3);
> or
> myAdd(1, 2);
>
> and after parsing their source files, generate the specialized functions
> with a different name in a separated utility file, replacing the
> occurrences of of use (that's the easy part).
> The utility file would look like:
>
> double _impl_double_myAdd(double x, double y) {
>   return x + y;
> }
>
> int _impl_int_myAdd(int x, int y) {
>   return x + y;
> }
>
> and the calls:
>
> _impl_double_myAdd(5.5, 3.3);
> and
> _impl_int_myAdd(1, 2);
>
> Can anyone point me in the right direction? I though about just replacing
> the usage cases of 'T' but that seems really manual and error prone.
>

You can call clang::Decl::print

on the template specialization declaration to see what it looks like after
substitution. We don't guarantee that the output will be valid C++ code in
all cases (and in fact, there are some constructs that can be produced by
template instantiation and cannot be written directly in C++, but they're
generally very rare), but it usually will be.

If you want a sample of what that looks like, try compiling your code with
"-Xclang -ast-print -S -o -"

For your original example (with the calls to myAdd moved to a function
f()), I get this with clang trunk:

template  T myAdd(T x, T y) {
return x + y;
}
template<> double myAdd(double x, double y) {
return x + y;
}
template<> int myAdd(int x, int y) {
return x + y;
}
void f() {
myAdd(5.5, 3.2998);
myAdd(1, 2);
}

Example case where the output is not valid C++:

template 
void destroy(T &t) { t.~T(); }
void f(int n) { destroy(n); }

... produces ...

template  void destroy(T &t) {
t.~T();
}
template<> void destroy(int &t) {
t.~int(); // this won't parse
}
void f(int n) {
destroy(n);
}
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] __builtin_constant_p(), __builtin_expect() and __builtin_types_compatible_p() and __has_builtin()

2019-08-09 Thread Richard Smith via cfe-users
On Fri, 9 Aug 2019 at 10:32, Chris Hall via cfe-users <
cfe-users@lists.llvm.org> wrote:

> On 09/08/2019 15:00, Matthew Fernandez wrote:
> >> On Aug 9, 2019, at 05:23, Chris Hall via cfe-users wrote:
> >>
> >> I find that __builtin_constant_p() works as expected, but
> >> __has_builtin(constant_p) denies it !
>
> > I believe you need __has_builtin(__builtin_constant_p).
>
> Ah :-(  So you do... sorry... I have no idea why I thought otherwise :-(
>
> >> Similarly __builtin_expect() and __builtin_types_compatible_p() !
>
> Except that __has_builtin(__builtin_types_compatible_p) also denies it.
>
> #include 
>
> int
> main(int argc, char* argv[])
> {
>   printf("__has_builtin(__builtin_types_compatible_p)=%d\n"
>"__builtin_types_compatible_p(int, int)=%d\n"
>"__builtin_types_compatible_p(int, long)=%d\n",
>   __has_builtin(__builtin_types_compatible_p),
> __builtin_types_compatible_p(int, int),
> __builtin_types_compatible_p(int, long)) ;
> }
>
> outputs:
>
> __has_builtin(__builtin_types_compatible_p)=0
> __builtin_types_compatible_p(int, int)=1
> __builtin_types_compatible_p(int, long)=0
>
> I hope I haven't missed something blindingly obvious this time.
>

This is a historical accident.

__has_builtin detects builtin *functions*. We also have a bunch of things
that start with __builtin and look somewhat like functions, but that take
types as arguments so can't actually be functions -- instead, they're
keywords with custom parsing rules. __has_builtin doesn't detect those
(because they're not builtin functions).

We've fixed this for such things we added recently, such as
__builtin_bit_cast and __builtin_FILE, but the older ones like
__builtin_types_compatible_p and __builtin_choose_expr and
__builtin_offsetof are unfortunately not detectable by __has_builtin.

There is another way to detect these: use
!__is_identifier(__builtin_types_compatible_p). That will evaluate to 1
whenever __builtin_types_compatible_p is not a valid identifier (because
it's a keyword) -- that is, whenever the feature is available. However,
__is_identifier was added in April 2014, and nearly all the builtins that
__has_builtin can't detect are older than that. So this technique isn't
really useful.

In practice, every version of Clang from the past 10 years supports
__builtin_types_compatible_p (in C mode). So you can just assume it exists.
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] __builtin_constant_p(), __builtin_expect() and __builtin_types_compatible_p() and __has_builtin()

2019-08-12 Thread Richard Smith via cfe-users
On Fri, 9 Aug 2019 at 19:48, Matthew Fernandez 
wrote:

> On Aug 9, 2019, at 14:58, Richard Smith via cfe-users <
> cfe-users@lists.llvm.org> wrote:
>
> On Fri, 9 Aug 2019 at 10:32, Chris Hall via cfe-users <
> cfe-users@lists.llvm.org> wrote:
>
>> On 09/08/2019 15:00, Matthew Fernandez wrote:
>> >> On Aug 9, 2019, at 05:23, Chris Hall via cfe-users wrote:
>> >>
>> >> I find that __builtin_constant_p() works as expected, but
>> >> __has_builtin(constant_p) denies it !
>>
>> > I believe you need __has_builtin(__builtin_constant_p).
>>
>> Ah :-(  So you do... sorry... I have no idea why I thought otherwise :-(
>>
>> >> Similarly __builtin_expect() and __builtin_types_compatible_p() !
>>
>> Except that __has_builtin(__builtin_types_compatible_p) also denies it.
>>
>> #include 
>>
>> int
>> main(int argc, char* argv[])
>> {
>>   printf("__has_builtin(__builtin_types_compatible_p)=%d\n"
>>"__builtin_types_compatible_p(int, int)=%d\n"
>>"__builtin_types_compatible_p(int,
>> long)=%d\n",
>>   __has_builtin(__builtin_types_compatible_p),
>> __builtin_types_compatible_p(int, int),
>> __builtin_types_compatible_p(int, long)) ;
>> }
>>
>> outputs:
>>
>> __has_builtin(__builtin_types_compatible_p)=0
>> __builtin_types_compatible_p(int, int)=1
>> __builtin_types_compatible_p(int, long)=0
>>
>> I hope I haven't missed something blindingly obvious this time.
>>
>
> This is a historical accident.
>
> __has_builtin detects builtin *functions*. We also have a bunch of things
> that start with __builtin and look somewhat like functions, but that take
> types as arguments so can't actually be functions -- instead, they're
> keywords with custom parsing rules. __has_builtin doesn't detect those
> (because they're not builtin functions).
>
> We've fixed this for such things we added recently, such as
> __builtin_bit_cast and __builtin_FILE, but the older ones like
> __builtin_types_compatible_p and __builtin_choose_expr and
> __builtin_offsetof are unfortunately not detectable by __has_builtin.
>
> There is another way to detect these: use
> !__is_identifier(__builtin_types_compatible_p). That will evaluate to 1
> whenever __builtin_types_compatible_p is not a valid identifier (because
> it's a keyword) -- that is, whenever the feature is available. However,
> __is_identifier was added in April 2014, and nearly all the builtins that
> __has_builtin can't detect are older than that. So this technique isn't
> really useful.
>
>
> This thread taught me something too, thanks :) The __is_identifier trick
> seems even more tricky to use than this implies. E.g. it returns true for
> __builtin_constant_p because that one is implemented as a function, as you
> describe. Does this mean to fully detect support for __builtin_foo I need
> something like `__has_builtin(foo) || __has_builtin(__builtin_foo) ||
> !__is_identifier(__builtin_foo)`?
>

Approximately all the function-like things that could be functions (that
is, where a use can be parsed as a function call, and in particular where
none of the arguments are types) are functions, and can be detected with
__has_builtin. Things that must have custom parsing logic are modeled as
keywords and can be detected by __is_identifier. You should never need both.

(In https://reviews.llvm.org/D66100 I'm proposing that we extend
__has_builtin to also be able to identify the builtins that we model as
keywords, but sadly that does nothing for versions of Clang we've already
released, so you still need to use the old techniques there.)


> While we’re on this topic, are the semantics of __is_identifier just “is
> not a keyword”? I ask because even when it returns true for a __-prefixed
> symbol, it’s not an indication you can use it in user code because it’s
> still reserved for use by the implementation. In fact __is_identifier even
> returns true for itself, which I guess is technically correct.
>

It's "is identifier", which (for identifier-shaped tokens) is almost but
not quite "is not a keyword", due to things like "and" which in C++ is
neither an identifier nor a keyword.

> In practice, every version of Clang from the past 10 years supports
> __builtin_types_compatible_p (in C mode). So you can just assume it exists.
>
>
> This is what I do too, as it’s widely supported back to every reasonable
> version of GCC as well.
>
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] clang-tblgen not installed

2019-09-06 Thread Richard Smith via cfe-users
On Thu, 5 Sep 2019 at 20:19, Alex Biddulph via cfe-users <
cfe-users@lists.llvm.org> wrote:

> Hi,
>
> Is there a reason why clang-tblgen is not installed with all of the
> other clang binaries?
>
> According to
> http://releases.llvm.org/8.0.0/docs/HowToCrossCompileLLVM.html
> clang-tblgen (along with llvm-tblgen) are needed if you want to
> cross-compile clang, but since clang-tblgen is not installed during the
> normal installation process this means that system packages (like those
> available for Arch Linux) don't provide a clang-tblgen requiring me to
> build a local clang that I can then use to cross-compile clang. This is
> at odds with LLVM which does install llvm-tblgen.
>
> Is this a bug, or is there a reason why clang-tblgen is not installed?
>

clang-tblgen is only used as part of the process of building clang itself,
and is tied to the revision of clang that it was built as part of. If
you're building a custom clang binary, you should build a clang-tblgen
binary yourself from the same sources that you're using to build the rest
of clang. A preinstalled version from a (potentially) different revision of
clang should not be expected to work. As such, I don't think it's
appropriate to install clang-tblgen.

The story for llvm-tblgen is a bit different: that should be part of the
development package for LLVM, and installed when the LLVM headers are
installed (not when the LLVM binaries are installed). The reason is that
out-of-tree backends for LLVM will want to invoke llvm-tblgen on
out-of-tree .td files, in order to generate portions of the code for those
backends. There is no comparable reason to want clang-tblgen installed --
even code using clang as a library, and using clang's C++ API rather than
the C API, has no need of clang-tblgen (assuming that the generated headers
are shipped as part of the development package, which they should be).
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] constexpr pointer-to-member-function broken in Clang 9?

2019-10-02 Thread Richard Smith via cfe-users
On Tue, 1 Oct 2019 at 10:42, Michael Price - Dev via cfe-users <
cfe-users@lists.llvm.org> wrote:

> Should this be ill-formed?
>
> struct C {
>   constexpr C() {}
>   constexpr bool f() const { return true; }
> };
> constexpr C c{};
>
> constexpr bool fails_9_0_0(const C* pc, bool (C::*pm)() const) {
>   return (pc->*pm)();
> }
> constexpr bool b = fails_9_0_0(&c, &C::f);
>
>
> Clang 9 produces a diagnostic stating “constexpr function never produces a
> constant expression” for `fails_9_0_0`. Works in Clang 8 as well as GCC and
> MSVC.
>

This was also filed as PR43519 and is now fixed in trunk.


> — Michael Price
>
> Sent from my iPhone
> ___
> cfe-users mailing list
> cfe-users@lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
>
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] Clang compilation options to solve the comaptible issue?

2019-11-03 Thread Richard Smith via cfe-users
On Thu, 31 Oct 2019 at 01:45, Guofeng Zhang via cfe-users <
cfe-users@lists.llvm.org> wrote:

> Hi,
>
> I just stat using clang 8 not long ago. I  need to compile our old c++
> source without changing it. It is compiled with Visual Studio before. Now I
> want to migrate to clang as the compiler.
>
> The following code segement can be compiled by clang:
>
> 1)  for (int i = 0 ; i < 6 ; i++ ) {
> 
>  }
>  int k = i ;  // compiler error
>

This code is relying on pre-standard C++ for loop scoping behavior (the
code has been invalid for all 21 years of standard C++). Clang does not
support this pre-standard behavior.


> 2) unsigned short *s = 
> wchar_t  *t = s ; // compiler error
>
> I tried -ffor-scope and -fshort-wchar, but does not solve the issues.
>
> are there clang compilation options to solve the issues?
>

For the latter, something like "-Dwchar_t=unsigned short" might mostly
work. (It won't support things like "wchar_t x = wchar_t(123);" though --
to support that you could put "typedef unsigned short my_wchar_t; #define
wchar_t my_wchar_t" into a -include'd header.)

Generally. if you have the combination of ancient pre-standard C++ code
that is invalid under any ISO C++ standard, and a requirement that you do
not modify the code, you're going to have problems. Sorry. That said, Clang
itself is open-source and modifiable, and it should be straightforward to
add support for the above two constructs to Clang and build your own
compiler that could perhaps accept this code. I'm not sure we'd want to
accept patches for those non-standard behaviors upstream, though.

Thanks for your help very much,
>
> Guofeng
> ___
> cfe-users mailing list
> cfe-users@lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
>
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] got wrong parameter type using clang

2019-12-11 Thread Richard Smith via cfe-users
On Tue, 10 Dec 2019, 22:45 henry ding via cfe-users, <
cfe-users@lists.llvm.org> wrote:

> simple test.cpp:
> void test(std::string xx,string bb,int aa){}
>
> clang usage:
> int getFuncInfo(Rewriter* TheRewrite,clang::ASTContext *Context, const
> FunctionDecl *func,FuncNode &node){
> clang::LangOptions LangOpts;
> LangOpts.CPlusPlus = true;
> Policy.FullyQualifiedName = 1;
>.
>   . ..
>for(unsigned int i=0; igetNumParams(); i++)
>{
>  string t =
> QualType::getAsString(func->getParamDecl(i)->getType().split(),Policy);
> string n =
>
> func->getParamDecl(i)->getName();//func->parameters()[i]->getQualifiedNameAsString()
>  cout << t + "#" + n << endl;
>  }
> }
>
> But,i got:
> int#xx  //should string#xx
> int#bb //should string#bb
> int#aa
>
> Has anyone encountered this situation ?


The bug is probably somewhere else. Make sure the proper language options
are set up before parsing the source file, and that you're printing out any
diagnostics. My guess would be that the source is failing to compile (wrong
options, or can't find some standard header, or something), and the
diagnostics are being discarded, and clang is replacing the parameter type
with 'int' in error recovery.

___
> cfe-users mailing list
> cfe-users@lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
>
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] is this compiller error

2020-02-12 Thread Richard Smith via cfe-users
On Fri, 7 Feb 2020 at 19:51, FRANČEK PRIJATELJ via cfe-users <
cfe-users@lists.llvm.org> wrote:

> /*
>
> Following code compiled with clang-cl on win10 generates 2 errors
> (while the same code compiled with MS cl compiles):
>
> t1.cpp(12,35): error: in-class initializer for static data member is not
> a constant expression
>  static const int64_t MIN_VALUE = -0x8000LL;
>   ^
> t1.cpp(15,39): error: in-class initializer for static data member is not
> a constant expression
>  static const int64_t MIN_VALUE1 = -9223372036854775808LL;
>^~
> 2 errors generated.
>

These expressions have undefined behavior due to exhibiting signed
overflow, and so are non-constant in C++11 onwards.

*/
>
> #include 
>
> static const int64_t MAX_VALUE = 0x7fffLL;
> static const int64_t MIN_VALUE = -0x8000LL;
>
> static const int64_t MAX_VALUE1 = 9223372036854775807LL;
> static const int64_t MIN_VALUE1 = -9223372036854775808LL;
>
>
> class X  {
>  static const int64_t MAX_VALUE = 0x7fffLL;
>  static const int64_t MIN_VALUE = -0x8000LL;
>
>  static const int64_t MAX_VALUE1 = 9223372036854775807LL;
>  static const int64_t MIN_VALUE1 = -9223372036854775808LL;
> };
>
>
> ___
> cfe-users mailing list
> cfe-users@lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
>
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] Need a GCC-free LLVM/Clang on Linux.

2020-02-19 Thread Richard Smith via cfe-users
On Thu, 23 Jan 2020 at 07:24, Christopher H Green via cfe-users <
cfe-users@lists.llvm.org> wrote:

> Hi,
>
> I've spent the last several days trying to build a fast, full-featured
> relocatable distribution of LLVM/Clang 9.0.1 on Linux RHEL7, which has an
> older native GCC (4.8.5)—I can't require the RH toolset. I have access to a
> modern version of GCC in order to make the stage-1 build, but I need the
> final product not only to be relocatable, but also to be free of any
> dependence on that GCC or its libraries. In other words, I want to be able
> to distribute an LLVM/CLang which defaults to compiling using libc++,
> libcxxabi, compiler-rt, libunwind, and ldd, and which itself depends
> neither on libstdc++ or  libgcc_s. I'd also like to be able to to provide
> LTO, but whether the compiler is itself the beneficiary of LTO is optional.
> As a final wish, I'd like the distribution as installed to serve as an SDK
> against which to build other components such as separately packaged lldb
> and f18. Oh, and I want a pony.
>
> Here's what I have so far (CMake cache files attached for stages 1 and 2).
> Invoked  in a separate build directory with:
>
> env CC=gcc-9 CXX=g++-9 \
> 'CXXFLAGS=-Wno-cast-function-type -Wno-deprecated-copy 
> -Wno-init-list-lifetime -Wno-pessimizing-move -Wno-redundant-move 
> -Wno-uninitialized -Wno-unused-function -Wno-unused-variable' \
> cmake -GNinja -C FNAL.cmake -DCMAKE_INSTALL_PREFIX= \
> -DBOOTSTRAP_LLVM_CXX_STD=c++17 
> ninja
> ninja install
>
> (The CXXFLAGS are just to keep the noise down during the stage-1 build).
>
> I appear (finally) to have a mostly functioning build *in situ*, but the
> installed compiler depends upon libstdc++ to be able to run, and I should
> have put --rtlib=compiler-rt in LINKER_FLAGS rather than CXX_FLAGS.
> Additionally, I haven't been able to come up with a good set of targets for
> LLVM_DISTRIBUTION_COMPONENTS, but when I do I think I need to exclude
> static libraries if I'm doing LTO, no?
>
> I suspect I need a three stage build—well, two stage 2s, at least—but any
> advice would be appreciated as I'm wandering around in the dark at this
> point.
>
I have a two-stage setup that builds a GCC-free Clang except for libgcc_s
(I've not looked at what's pulling that in yet, but I expect that's
resolvable).

My stage1 cmake setup has: -DCLANG_DEFAULT_CXX_STDLIB=libc++
-DCLANG_DEFAULT_RTLIB=compiler-rt
My stage2 cmake setup additionally has: -DLIBCXXABI_USE_LLVM_UNWINDER=ON
-DLIBCXXABI_USE_COMPILER_RT=ON -DLIBCXX_USE_COMPILER_RT=ON
(and points CMAKE_C_COMPILER and CMAKE_CXX_COMPILER at the stage1 clang).

There might be some other things you need, I'm not sure. But it should be
doable in two stages.

> Many thanks for any help,
>
> Chris.
>
>
> ___
> cfe-users mailing list
> cfe-users@lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
>
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] How to check whether a type is_copy_assignable?

2020-02-19 Thread Richard Smith via cfe-users
On Thu, 6 Feb 2020 at 12:13, Weston Carvalho via cfe-users <
cfe-users@lists.llvm.org> wrote:

> HI,
>
> I'm trying to write a tool that uses the AST to look at all the class
> declarations in our codebase and get some metrics on our use of special
> member functions. (How many classes are copyable, how many have
> ctors without the corresponding assignment operator, etc.) I'm running into
> some problems with implicitly declared special members. For example:
>
> class UserDefCopy {
>  public:
>   UserDefCopy(const UserDefCopy&) {}
>   UserDefCopy& operator=(const UserDefCopy&) { return *this; }
> };
> class ContainsUserDefCopy {
>  private:
>   UserDefCopy x_;
> };
>
> UserDefCopy has a CXXConstructorDecl for its copy constructor and a
> CXXMethodDecl for the copy-assign operator, so I can use the methods on the
> decls to get the info I need (isDeleted, isExplicitlyDefaulted, getAccess,
> etc.) However, ContainsUserDefCopy's copy-assign operator is implicit, so
> there's no decl for it. Since there's no decl, I can't differentiate
> between a class with an implicitly defaulted copy-assign and one with an
> implicitly deleted copy-assign. ContainsUserDefCopy does have a
> declaration for its copy constructor, but AFAICT from looking at
> clang::Sema::AddImplicitlyDeclaredMembersToClass
> ,
> that's because special members with the needs_overload_resolution tag are
> eagerly generated while others are deferred. I don't understand why the
> ctor has the tag while the assign operator doesn't, though.
>
> The questions I have are:
>
>1. What makes a method needs_overload_resolution? The docs in
>CXXRecordDecl just say that it "[determines] whether we need to
>eagerly declare a defaulted [member] for this class."
>
> Once the class is completely defined, the definition data accessors on
CXXRecordDecl (eg, hasTrivialCopyConstructor) are required to return
accurate information about the class. The "needs overload resolution" flag
is set by CXXRecordDecl if it couldn't work those properties out by itself
and needs Sema to help. For example, if it's not trivially obvious what
constructor would be used to copy a subobject of a class (see
CXXRecordDecl::hasSimpleCopyConstructor), CXXRecordDecl sets the "need
overload resolution" flag so that Sema can properly work out whether that
class's copy constructor is trivial.

This flag is just an implementation detail, and doesn't have any
interesting meaning outside of the implementation of CXXRecordDecl and Sema.

>
>1. Is there a different way I should query the AST so that I see any
>decls that were deferred during the Sema step? Or some other way to get
>this information? Trying to use an implicitly deleted copy assignment
>operator is a compiler error, so that information is obviously available
>*somewhere*.
>
> It depends on what question you want the answer to. I'd guess (based on
the subject of your email) that you want the same answer that
is_copy_assignable would give, which means you want to know whether a
certain assignment expression would be valid (and note that the assignment
expression might be implemented by something other than a copy-assignment
operator in general, C++ being what it is). Probably the easiest way to
query that would be to call Sema::BuildTypeTrait and call
TypeTraitExpr::getValue() on the result.

You should be aware that making this query may have side-effects (in
particular, it may trigger template instantiations and result in errors
outside of the immediate context). But that's fundamental to the question
you're asking, I'm afraid.
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] How to check whether a type is_copy_assignable?

2020-02-20 Thread Richard Smith via cfe-users
On Thu, 20 Feb 2020 at 09:33, Weston Carvalho 
wrote:

> Richard,
>
> Thanks for your response!
>
> I'm currently getting all the CXXRecordDecls using the ASTMatchFinfer.
> AFAICT, I can't access Sema since the MatchFinder is an ASTConsumer instead
> of a SemaConsumer. I guess I can make my own MatchFinderWithSema; do you
> know of a better way?
>

I don't know if there's any prebuilt way to do this.


> Also, is_copy_assignable is only one of the pieces of info I'm looking
> for. The full list if what I'm trying to get for each special member is:
>
>1. Does it exist?
>2. Is it trivial?
>3. Is it implicitly defined?
>4. If it's not implicitly defined, is it user defined or is it
>explicitly defaulted?
>5. What's the Access Specifier?
>6. If it's a copy ctor or assign, is its argument const T& or T&?
>7. If it's an assignment operation, does it return T&?
>
> I think I can get all of these by constructing type traits or expressions
> with Sema, at least modulo the weird stuff you mentioned. (It would be nice
> if I could detect/exclude those cases, but I don't think it's essential.)
>

Do you actually want information about special members, or do you want to
know what (eg) a construction or assignment expression would do? These are
different questions in C++, because overload resolution might pick
something other than a special member function in order to answer them.
is_copy_assignable answers the question of whether an expression of the
form "a = b;" would be valid, which might or might not involve special
member functions.

If you actually want information about special members, then the various
methods on CXXRecordDecl may be the best way to go. Note that some of the
questions above are then trivial, and don't have dedicated accessor
methods. For example, the answer for "Does it exist?" for a copy assignment
operator is simply "yes", for every class. (If you don't declare one, one
is always declared for you.) Alternatively, you can call
Sema::ForceDeclarationOfImplicitMembers and then look for the methods you
care about.

I don't understand how this could trigger template instantiations or
> errors; could you elaborate? Would that only be possible if the class I'm
> checking is an instantiation of a template class itself or if its copy
> constructor was templated?
>

It depends. If what you want is to ask questions about the special member
functions, then most of those can be answered without triggering
instantiations (or at least, we will have already triggered those
instantiations when the answers weren't easy). If you instead want to know
"would `a = b;` invoke a trivial assignment operator?" then determining
that can involve evaluating arbitrary metaprogramming constructs, which can
result in errors.

Thanks again for your help,
> Weston
>
> On Wed, Feb 19, 2020 at 2:49 PM Richard Smith 
> wrote:
>
>> On Thu, 6 Feb 2020 at 12:13, Weston Carvalho via cfe-users <
>> cfe-users@lists.llvm.org> wrote:
>>
>>> HI,
>>>
>>> I'm trying to write a tool that uses the AST to look at all the class
>>> declarations in our codebase and get some metrics on our use of special
>>> member functions. (How many classes are copyable, how many have
>>> ctors without the corresponding assignment operator, etc.) I'm running into
>>> some problems with implicitly declared special members. For example:
>>>
>>> class UserDefCopy {
>>>  public:
>>>   UserDefCopy(const UserDefCopy&) {}
>>>   UserDefCopy& operator=(const UserDefCopy&) { return *this; }
>>> };
>>> class ContainsUserDefCopy {
>>>  private:
>>>   UserDefCopy x_;
>>> };
>>>
>>> UserDefCopy has a CXXConstructorDecl for its copy constructor and a
>>> CXXMethodDecl for the copy-assign operator, so I can use the methods on the
>>> decls to get the info I need (isDeleted, isExplicitlyDefaulted, getAccess,
>>> etc.) However, ContainsUserDefCopy's copy-assign operator is implicit,
>>> so there's no decl for it. Since there's no decl, I can't differentiate
>>> between a class with an implicitly defaulted copy-assign and one with an
>>> implicitly deleted copy-assign. ContainsUserDefCopy does have a
>>> declaration for its copy constructor, but AFAICT from looking at
>>> clang::Sema::AddImplicitlyDeclaredMembersToClass
>>> ,
>>> that's because special members with the needs_overload_resolution tag
>>> are eagerly generated while others are deferred. I don't understand why the
>>> ctor has the tag while the assign operator doesn't, though.
>>>
>>> The questions I have are:
>>>
>>>1. What makes a method needs_overload_resolution? The docs in
>>>CXXRecordDecl just say that it "[determines] whether we need to
>>>eagerly declare a defaulted [member] for this class."
>>>
>>> Once the class is completely defined, the definition data accessors on
>> CXXRecordDecl (eg, hasTrivialCopyConstructor) are required to return
>> accurate information about the cl

Re: [cfe-users] Final C++20 rules and -Wambiguous-reversed-operator

2020-03-15 Thread Richard Smith via cfe-users
On Thu, 12 Mar 2020 at 15:14, Romain GEISSLER via cfe-users <
cfe-users@lists.llvm.org> wrote:

> Hi,
>
> It looks like the working of C++20 introduced some breaking
> compatibilities with some C++17 accepted patterns. From what I read in
> https://reviews.llvm.org/rL375306 these incompatibilities weren’t really
> intented by the initial C++20 proposal, and thus broken patterns were still
> allowed as an extension, but would warn with -Wambiguous-reversed-operator
> enabled by default. Richard Smith had some hope that the C++20 standard
> would be fixed before being final.
>
> C++20 is not fully finalized yet, but this date is approaching. What’s the
> state of the standard now ? Have the comparison issues been fixed ?


No, we still don't have a resolution from the C++ committee, but it's being
discussed by various implementers, and we hope to present to the committee
a suggested set of changes to minimize the pain to users as soon as we can.
I expect we will change /something/ as a DR fix against C++20, but the
exact details are unclear.

If not, what do you suggest to users ? Fix the code (when it’s actually
> possible and make sense), or compile with -Wno-ambiguous-reversed-operator
> ? I am asking this question in the particular case of boost date_time:
> https://github.com/boostorg/date_time/issues/132 where I am actually
> unsure this is a good idea to change the existing code.
>

If you can change the code in a way that's compatible with the C++20 rules,
that will give you the best portability across compilers in the short term.
If Boost is prepared to wait until this is fixed before supporting
-std=c++20, then that would seem reasonable too.
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] [EXT] Final C++20 rules and -Wambiguous-reversed-operator

2020-03-19 Thread Richard Smith via cfe-users
On Thu, 19 Mar 2020 at 05:28, Romain GEISSLER 
wrote:

> > Le 15 mars 2020 à 20:14, Richard Smith  a écrit :
> >
> > No, we still don't have a resolution from the C++ committee, but it's
> being discussed by various implementers, and we hope to present to the
> committee a suggested set of changes to minimize the pain to users as soon
> as we can. I expect we will change /something/ as a DR fix against C++20,
> but the exact details are unclear.
>
> Hi,
>
> Thanks for the heads up.
>
> I am not sure how valid is my request, but I found a case where I wished
> -Wambiguous-reversed-operator would avoid what today with clang 10 is a
> strong error.
>
> Consider this code: the == comparison warning is avoidable with
> -Wambiguous-reversed-operator, but not the != comparison. This make
> existing C++17 code behavior non-symetric when migrating to pack C++20, and
> a bit awkward for users:
>
> template  struct A
> {
> bool operator==(const T&) const;
> bool operator!=(const T&) const;
> };
>
> struct B : public A {};
>
> bool f()
> {
> bool a1 = B() == B(); // Works, only a -Wambiguous-reversed-operator
> warning
> bool a2 = B() != B(); // Strong error, which you can't avoid with
> -Wno-ambiguous-reversed-operator flag
> }
>
> Do you think that in the meantime while we wait for the C++ committee to
> standardize a real DR clang 10 should be update to also just warns in such
> cases involving != ?


At this point it's likely too late to do anything different for Clang 10...
but the rule we're discussing to fix this issue would make the above case
work. I'll see about implementing that sooner rather than later.
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] clang and C++: exporting member function template from library using attribute visibility("default")

2020-04-05 Thread Richard Smith via cfe-users
On Mon, 30 Mar 2020 at 14:19, Alexis Murzeau via cfe-users <
cfe-users@lists.llvm.org> wrote:

> Hi,
>
> When using clang, I discovered that it errors out where other compilers
> doesn't (GCC and MSVC).
>
> I'm trying to do this:
>  - Have a library compiled with -fvisibility=hidden and adding
> __attribute__((visibility("default")))
>only for stuff that must be exported from the library .so.
>
>  - Have an exported class (with __attribute__((visibility("default"
> that
>declares a member function template
>
>  - A cpp file in the library does does instantiation of that member
> function
>template for all applicable types that would ever be usable by that
> member function template.
>

If you want one source file to provide instantiations for use by a
different source file, it's not sufficient to merely trigger those
instantiations. That only generates a discardable definition of the
instantiation, and if (for example) that definition is inlined, no symbol
will be provided for other translation units to link against. Instead you
need to use an explicit instantiation. (See
https://en.cppreference.com/w/cpp/language/function_template#Explicit_instantiation
)


> When compiling that library, the member function template instantiations
> are
> not being exported from the library (they are hidden).
>
> The error comes then when an executable try to use that function, but
> compilation fails because of undefined reference to `void
> NetworkPacketLogger::logType(T1 const*)'.
>
>
> In a lib.h:
> ```
> // An enum defining the network packet
> enum class Opcode {
> T1,
> T2
> };
>
> // Base class
> struct NetworkPacket {
> NetworkPacket(enum Opcode t) : type(t) {}
>
> enum Opcode type;
> };
>
> // Sample of possible network packets
> struct T1 : public NetworkPacket {
> T1() : NetworkPacket(Opcode::T1) {}
> int value;
> };
>
> struct T2 : public NetworkPacket {
> T2() : NetworkPacket(Opcode::T2) {}
> float value;
> };
>
> // Class to log a network packet
> class __attribute__((visibility("default"))) NetworkPacketLogger {
> public:
> // "Slow" function that find the correct packet opcode and log
> it's content
> // vvv this function is exported just because of the attribute on
> the NetworkPacketLogger, OK
> static void logAbstractType(struct NetworkPacket* abstractData);
>
> // Fast function that doesn't have to find the packet opcode
> // It does just a log of data->value
> // T can only be either T1 or T2
>
> // vvv this is the hidden function that should be exported from
> the lib
> template static void logType(const T* data)
> __attribute__((visibility("default")));
> };
> ```
>
> In a lib.cpp:
> ```
> template
> void NetworkPacketLogger::logType(const T* data) {
> std::cout << data->value;
> }
>
> void NetworkPacketLogger::logAbstractType(struct NetworkPacket*
> abstractData) {
> // Possibly generated code is there are many possible network
> packets
> // This will implicitely instanciate all possible combination of
> NetworkPacketLogger::logType
> // I want these instanciations to be available by user of the
> library
>

To make these available to users, you should explicitly instantiate them as
follows:

template void NetworkPacketLogger::logType(const T1*);
template void NetworkPacketLogger::logType(const T2*);

switch(abstractData->type) {
> case Opcode::T1:
> logType(static_cast(abstractData));
> break;
> case Opcode::T2:
> logType(static_cast(abstractData));
> break;
> }
> }
> ```
>
>
> I found by tweaking the code that, if I add a
> __attribute__((visibility("default")))
> on struct T1 and struct T2, then logAbstractType and
> logAbstractType are exported.
>
> But why is this required for clang ?
> It seems to be like this old bug:
> https://bugs.llvm.org/show_bug.cgi?id=8457
>
> Is this expected ?
>

Yes. You're probably just getting lucky with the other compilers, and they
happen to not inline either of the 'logType' functions.


> Shouldn't a warning be emitted when a function that should be
> "visibility("default")"
> is not because of one of the arguments use a struct with
> visibility("hidden") ?
>
>
> I'm attaching a test case.
> Can be compiled with something like this:
> ```
> mkdir build && cd build
> CC=clang-9 CXX=clang++-9 cmake ..
> make
> nm -CD liblib.so  | grep logType
> ```
>
> nm will print only this (no NetworkPacketLogger::logType):
> 11b0 T NetworkPacketLogger::logAbstractType(NetworkPacket*)
> 1260 W void NetworkPacketLogger::logType(T2 const*)
> 1290 W void NetworkPacketLogger::logType(T3 const*)
>
>
> Thanks for your hindsight :)
>
> --
> Alexis Murzeau
> PGP: B7E6 0EBB 9293 7B06 BDBC  2787 E7BD 1904 F480 937F
> _

Re: [cfe-users] order of object files at link affects exception catching

2020-04-05 Thread Richard Smith via cfe-users
On Sun, 5 Apr 2020 at 15:31, krokus via cfe-users 
wrote:

> First of all a preface - This problem was spotted while trying to
> build a large C++ project which links a close to 100 of object file
> together, plus libraries. I can't replicate this behavior in a simple
> isolated test. Just want to understand if potentially this may be
> caused by clang's compiler or linker behavior (missed flag, or
> optimization effect/bug). The project builds and runs correctly with
> GCC.
>
> Compiler: clang-10 on OSX 10.13
>
> The project builds fully without errors and the final binary
> executable is produced. The binary starts up ok and presents a prompt.
> However any exception-based processing (like input errors are expected
> to show a message and continue, or catching Ctrl+C and processing into
> a message and continue)  result in uncaught exception and ends in
> abort(). Basically, the libc++ calls std::terminate(), as if the
> proper catch statement is missing, which clearly is in the code.
> Somehow the exception unwind stack gets broken.
>
> The code links a large number of objects and a few .a libraries, so I
> tried to put the individual objects into another .a lib to try to
> eliminate the order effects. Still, the resulting binary has the
> exception catching issues.
>
> Then I tried to craft a simple test (which does not use any of the
> actual project's code)  that has throw/catch and then linked it in the
> same way. The results:
>  * when the test code is linked from the .a library (with all objects
> as above), the exceptions are processed ok.
>  * when the test code is linked with all the objects above specified
> on the command line, the exception issues are back.
>

Only objects that contain referenced symbols get pulled in from archives,
so using a .a library will tend to result in fewer objects being linked in
than specifying the .o files on the command line. That might explain part
of the difference you're seeing here.


> Obviously, the simple test code does not need any of the code from the
> other objects, yet the resulting code appears somehow broken. Granted,
> the linker will  have to resolve all dependecies it finds on the
> command line and tie it into the binary, still none of those functions
> should be executed by the sample test code.
>
> Finally, I tried to change the order of the project's object files at
> line and put the object file which does the actual throw, right next
> to the main's object file. To my surprise, the exceptions were caught
> ok... But too soon to celebrate, exceptions tripped in other parts of
> the code still were not caught properly.
>
> So the bottom line, some how the exceptions table gets messed up in
> the process on linking. I can't think of any other way to diagnose
> this.
>
> By the way, the very same code is properly linked and functioning when
> using GCC default compile/link options.
>
> I tired without success -fno-lto to disable link-time-optimization,
> but that's default anyway.
>
> To reiterate the questions:
> 1. Why would order of the object files matter for correct exception
> processing?
>

The most likely explanation is that your program contains a violation of
C++'s "One Definition Rule" (ODR). Specifically, you probably have a
function or class that's defined in different ways in two different source
files, and the behavior of your program depends on which one gets picked at
link time. (Worse, there are ways in which we can end up picking one
version from one .o file and a different version from a different .o file.)
Given the symptoms, it's possible that this is happening because part of
your program is built with -fno-exceptions and part of your program is
build without that flag, and an exception in question is propagating
through a (perhaps inline) function that was built both ways. But that's
just a guess.


> 2. Are there some clang's options specific for such cases?
>

Do you still see the issue with -O0? Do you still see the issue if you
explicitly add -fexceptions to every compilation?
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] order of object files at link affects exception catching

2020-04-14 Thread Richard Smith via cfe-users
On Wed, 8 Apr 2020 at 10:14, krokus via cfe-users 
wrote:

> Richard,
>
> Thanks for the quick response; it gave me some directions to
> investigate further, otherwise it seemed I got stuck trying to make
> sense of many moving pieces in this puzzle. So, my understanding is
> that generally the run-time exception handling should _not_  depend on
> the order of the linkage (provided there're no violations as you
> mentioned). This is unlike the familiar case of order of object files
> affecting the linker's resolutions of external symbols, where the
> order _does_ matter.  That means what I'm seeing is rather anomalous,
> not a by-design behavior.
>
> Now, looking into the ideas of the ODR violation, I realise that in
> the set up I'm using, the clang (installed from pre-built
> pack...@llvm.org) is used with '-stdlib=libc++', so the link pulls the
> libc++.dylib and the libc++abi.dylib. The compiler gets clang's libc++
> includes, the linker resolves these from clang's /lib, however OSX
> (10.13) has its own set of these .dynlibs in /usr/lib; system's
> libSystem pulls these (via libobjc.dylib). So the resulting binary
> loads two sets of libc++ and libc++abi.
>
> Are there any linkages between the clang's supplied libc++ and
> system's libc++abi, or it's meant to use exclusively clang's libc++?
>

I'm afraid I don't know exactly how our packages nor the Mac OS X versions
are configured. It's possible there's some mismatch here. If this is
specific to the libc++ dylib that's included in OS X, the Apple folks would
probably be interested in you contacting them directly.

One other thing that sometimes goes wrong when exceptions are thrown but
can't be caught is that the type information on the throw and catch sides
doesn't match, usually because of visibility attributes (or command-line
flags) causing one or both versions of the type to be considered
DSO-internal. Can you catch the exception with "catch (...)"?


> Could this be the reason for exception breakdown? I understand that
> generally there should be only one libc++abi for the whole
> application, this way the type_info is common across all classes, and
> thus exceptions are correctly typed. This may explain why a sample
> test (try/throw/catch) works in isolation, as it may not cross from
> one set of libc++abi into the other.
>

If you do have two different libc++abis in the same process (maybe one
statically and one dynamically linked?) then it seems plausible that
exception throw/catch would break down, because they would have different
ideas of what some of the key globals involved in exception throw/catch are
(for example, primitive type_info objects).


> I'm thinking what test code could I craft that would possibly trigger
> the use of both clang's and system's libc++abi? Clearly, the simple
> try/throw/catch works OK whether with or without -rpath to clang's
> lib.
>
> > Given the symptoms, it's possible that this is happening because part of
> your program is built with -fno-exceptions and part of your program is
> build without that flag, and an exception in question is propagating
> through a (perhaps inline) function that was built both ways. But that's
> just a guess.
>
> I tried to rebuild the whole application with -fexceptions; still the
> same symptoms. Also tried with -funwind-tables. The issue is present
> wth -O0 too. Reading on this, back in time Apple was advising Xcode
> users _not_ to use -no_compact_unwind switch, as it led to similar
> issue of exceptions not getting caught. Not sure what exactly was the
> effect of that switch, but clang does not seem to have this switch
> and, well, exceptions are being caught in isolated sample test.
>
> I appreciate your input.
> ___
> cfe-users mailing list
> cfe-users@lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
>
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] Linking problem with implicit instantiation of constructor/destructor

2020-04-20 Thread Richard Smith via cfe-users
In the latest draft, this is [temp.pre]/10:

"""
A definition of a function template, member function of a class template,
variable template, or static data member of a class template shall be
reachable from the end of every definition domain (6.3) in which it is
implicitly instantiated (13.9.1) unless the corresponding specialization is
explicitly instantiated (13.9.2) in some translation unit; no diagnostic is
required.
"""

... which might be slightly easier to read in the pre-C++20 version
(without the modules-awareness), where it is [temp]/7:

"""
A function template, member function of a class template, variable
template, or static data member of a class template shall be defined in
every translation unit in which it is implicitly instantiated unless the
corresponding specialization is explicitly instantiated in some translation
unit; no diagnostic is required.
"""

On Sun, 19 Apr 2020 at 12:00, David Blaikie  wrote:

> Yeah, can't seem to divine the concrete wording here either - perhaps
> Richard will have a moment to chime in.
>
> On Sun, Apr 19, 2020 at 6:10 AM Jaroslav Zeman via cfe-users <
> cfe-users@lists.llvm.org> wrote:
>
>> >
>> > What happens if you change the order of the .cpp files, putting
>> > template.cpp first; is it stil unresolved?
>> >
>> > clang++ -o test template.cpp main.cpp
>>
>> The order doesn't matter.
>>
>> > I don't believe this code is valid according to C++. I believe it would
>> > require an explicit instantiation of the ctor/dtor somewhere to make
>> that
>> > code valid - though I don't have chapter and verse on the spec at hand
>> just
>> > now to back that up.
>>
>> I tried to read the c++ specs, but didn't find anything, that would
>> clearly
>> state, if this is correct or incorrect. But the specs are too complicated
>> for
>> me to understand.
>>
>> My opinion is that it is bad to rely on implicit instantiation to happen
>> somewhere and don't do the explicit one. So I've already fixed all these
>> problems in our code and now I am just curious, what others think about
>> it.
>>
>> JZ.
>>
>>
>>
>> ___
>> cfe-users mailing list
>> cfe-users@lists.llvm.org
>> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
>>
>
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] Get AST of uncomplete C++ code

2020-04-24 Thread Richard Smith via cfe-users
On Tue, 21 Apr 2020 at 05:41, Dr S3curity via cfe-users <
cfe-users@lists.llvm.org> wrote:

> Hi,
>
> Imagine the very basic code below, it has some missing elements, we dont
> have the foo() function and MyClass class,
>
> ```test.cpp
> int main(int argc, char *argv[])
> {
> MyClass* mc = new MyClass();
> mc.get_count();
> foo(1, 2, 3);
> std::cout << "this is a test" << endl;
> }
> ```
>
> How can I get AST for that code?
> I tried `clang -Xclang -ast-dump -fsyntax-only test.cpp`, I can get the
> AST tree but without MyClass and foo() function, it doesn't even say foo is
> a function with 3 integer parameters.
>
> This can be problematic for different cases for example IDE's where you
> dont have all the project dependencies but yet you need to know what are
> the elements in your code.
>
> Is that possible to do with libclang? Any other suggestions are welcome.
>

You can request that more invalid portions of the AST are retained by using
`-Xclang -frecovery-ast`. In this case, that will preserve the function
call expression as a RecoveryExpr. For now at least, we don't have the
ability to preserve AST information for the invalid "new MyClass" nor the
expression using of undeclared "std::cout" and "endl", but
-frecovery-ast is expected to improve over time to retain more such AST
nodes. (And perhaps eventually it will be enabled by default, at which
point the flag for it might disappear. We don't guarantee any forward
compatibility with -Xclang flags.)
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] Compiling C++ 20 Example from 24.6.4.1 [range.istream.overview] produces errors with libstdc++ 10

2020-05-13 Thread Richard Smith via cfe-users
On Wed, 6 May 2020 at 09:24, Ray Lischner via cfe-users <
cfe-users@lists.llvm.org> wrote:

> I am using clang++ 10 with GCC libstdc++ 10 prerelease. I tried
> compiling the example from section 24.6.4.1 [range.istream.overview]. It
> works with g++ 10 but with clang++ 10 -std=c++20, I get
> constraint-failure errors.
>
> program:
> #include 
> #include 
> #include 
> #include 
> #include 
>
> int main()
> {
>using namespace std;
>using namespace ranges;
>auto ints = istringstream{"0 1  2   3 4"};
>ranges::copy(istream_view(ints), ostream_iterator{cout, "-"});
>// prints0-1-2-3-4-
> }
>
> $ clang++ -std=c++20 -o range_istream_overview \
> range_istream_overview.cpp
>
> Gist of the errors is that the istream_view fails the constraints for a
> range because ranges::begin() fails its constraint for the
> basic_istream_view::begin() member function:
>
> { __detail::__decay_copy(__t.begin()) } -> input_or_output_iterator;
>
> Any ideas what's wrong or how to proceed?
>

Please could you provide the complete set of diagnostics from the
compilation?
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] Compiling C++ 20 Example from 24.6.4.1 [range.istream.overview] produces errors with libstdc++ 10

2020-05-15 Thread Richard Smith via cfe-users
On Thu, 14 May 2020 at 03:50, Ray Lischner  wrote:

> On 5/13/20 10:09 PM, Richard Smith wrote:
> > On Wed, 6 May 2020 at 09:24, Ray Lischner via cfe-users
> > mailto:cfe-users@lists.llvm.org>> wrote:
> >
> > I am using clang++ 10 with GCC libstdc++ 10 prerelease. I tried
> > compiling the example from section 24.6.4.1
> > [range.istream.overview]. It
> > works with g++ 10 but with clang++ 10 -std=c++20, I get
> > constraint-failure errors.
> >
> > program:
> > #include 
> > #include 
> > #include 
> > #include 
> > #include 
> >
> > int main()
> > {
> > using namespace std;
> > using namespace ranges;
> > auto ints = istringstream{"0 1  2   3 4"};
> > ranges::copy(istream_view(ints),
> > ostream_iterator{cout, "-"});
> > // prints0-1-2-3-4-
> > }
> >
> > $ clang++ -std=c++20 -o range_istream_overview \
> > range_istream_overview.cpp
> >
> > Gist of the errors is that the istream_view fails the constraints
> for a
> > range because ranges::begin() fails its constraint for the
> > basic_istream_view::begin() member function:
> >
> > { __detail::__decay_copy(__t.begin()) } -> input_or_output_iterator;
> >
> > Any ideas what's wrong or how to proceed?
> >
> >
> > Please could you provide the complete set of diagnostics from the
> > compilation?
>
> In file included from range_istream_overview.cpp:1:
> In file included from
>
> /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/algorithm:61:
> In file included from
>
> /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/bits/stl_algobase.h:65:
> In file included from
>
> /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/bits/stl_iterator_base_types.h:71:
> /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/bits/iterator_concepts.h:884:13:
>
> error: no matching function for call to '__ranges_begin'
>  = decltype(__detail::__ranges_begin(std::declval<_Tp&>()));
> ^~~~
> /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/bits/range_access.h:874:5:
>
> note: in instantiation of template type alias '__range_iter_t' requested
> here
>  using iterator_t = std::__detail::__range_iter_t<_Tp>;
>  ^
> /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/ranges:134:43:
>
> note: in instantiation of template type alias 'iterator_t' requested here
>data() requires contiguous_iterator>
>^
> /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/ranges:956:14:
>
> note: in instantiation of template class
> 'std::ranges::view_interface std::char_traits > >' requested here
>  : public view_interface>
>   ^
> range_istream_overview.cpp:12:16: note: in instantiation of template
> class 'std::ranges::basic_istream_view
>  >' requested here
>ranges::copy(istream_view(ints), ostream_iterator{cout, "-"});
> ^
>

OK, so the relevant part is this:


> /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/bits/iterator_concepts.h:867:7:
>
> note: candidate template ignored: constraints not satisfied [with _Tp =
> std::ranges::basic_istream_view >]
>__ranges_begin(_Tp& __t)
>^
> /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/bits/iterator_concepts.h:865:16:
>
> note: because 'is_array_v std::char_traits > >' evaluated to false
>requires is_array_v<_Tp> || __member_begin<_Tp&> ||
> __adl_begin<_Tp&>
> ^
> /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/bits/iterator_concepts.h:865:35:
>
> note: and 'std::ranges::basic_istream_view std::char_traits > &' does not satisfy '__member_begin'
>requires is_array_v<_Tp> || __member_begin<_Tp&> ||
> __adl_begin<_Tp&>
>^
> /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/bits/iterator_concepts.h:849:33:
>
> note: because '__detail::__decay_copy(__t.begin())' would be invalid: no
> member named 'begin' in 'std::ranges::basic_istream_view std::char_traits >'
>{ __detail::__decay_copy(__t.begin()) } ->
> input_or_output_iterator;
> ^
> /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/bits/iterator_concepts.h:865:59:
>
> note: and 'std::ranges::basic_istream_view std::char_traits > &' does not satisfy '__adl_begin'
>requires is_array_v<_Tp> || __member_begin<_Tp&> ||
> __adl_begin<_Tp&>
>^
> /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/bits/iterator_concepts.h:859:29:
>
> note: because '__detail::__decay_copy(begin(__t))' would be invalid:
> call to deleted function 'begin'
>{ __detail::__decay_copy(begin(__t)) } ->
> i

Re: [cfe-users] Compiling C++ 20 Example from 24.6.4.1 [range.istream.overview] produces errors with libstdc++ 10

2020-05-26 Thread Richard Smith via cfe-users
On Tue, 26 May 2020 at 07:39, Ray Lischner via cfe-users <
cfe-users@lists.llvm.org> wrote:

> On 5/15/20 6:53 PM, Richard Smith wrote:
> > Can you try calling begin() on an istream_view& directly, and see
> > if you get the same error?
>
> $ cat istream_begin.cpp
> #include 
> #include 
> #include 
> #include 
>
> int main()
> {
>auto ints = std::istringstream{"0 1 2 3 4"};
>auto view{ std::ranges::istream_view(ints) };
>auto begin{ std::ranges::begin(view) };
>

Here, Clang claims istream_view has no member named 'begin', during
satisfaction checking.


>assert(&*view.begin() == &*begin);
>

... but Clang accepts this. There's definitely something wrong here.

Can you humor me for a second and try calling 'view.begin()' directly
before using std::ranges::begin? (I'm suspicious that we're somehow not
triggering instantiation of istream_view until too late; calling
'view.begin()' earlier would resolve the problem if that's the case.)


> }
> $ g++ -std=c++20 istream_begin.cpp
> $ ./a.out
> $ clang++ -std=c++20 istream_begin.cpp
> In file included from istream_begin.cpp:2:
> In file included from
>
> /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/iostream:39:
> In file included from
>
> /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/ostream:38:
> In file included from
>
> /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/ios:40:
> In file included from
>
> /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/bits/char_traits.h:39:
> In file included from
>
> /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/bits/stl_algobase.h:65:
> In file included from
>
> /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/bits/stl_iterator_base_types.h:71:
> /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/bits/iterator_concepts.h:902:13:
>
> error: no matching function for call to '__ranges_begin'
>  = decltype(__detail::__ranges_begin(std::declval<_Tp&>()));
> ^~~~
> /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/bits/range_access.h:874:5:
>
> note: in instantiation of template type alias '__range_iter_t' requested
> here
>  using iterator_t = std::__detail::__range_iter_t<_Tp>;
>  ^
> /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/ranges:134:43:
>
> note: in instantiation of template type alias 'iterator_t' requested here
>data() requires contiguous_iterator>
>^
> /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/ranges:956:14:
>
> note: in instantiation of template class
> 'std::ranges::view_interface std::char_traits > >' requested here
>  : public view_interface>
>   ^
> istream_begin.cpp:9:14: note: in instantiation of template class
> 'std::ranges::basic_istream_view >'
> requested here
>auto view{ std::ranges::istream_view(ints) };
>   ^
> /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/bits/iterator_concepts.h:885:7:
>
> note: candidate template ignored: constraints not satisfied [with _Tp =
> std::ranges::basic_istream_view >]
>__ranges_begin(_Tp& __t)
>^
> /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/bits/iterator_concepts.h:883:16:
>
> note: because 'is_array_v std::char_traits > >' evaluated to false
>requires is_array_v<_Tp> || __member_begin<_Tp&> ||
> __adl_begin<_Tp&>
> ^
> /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/bits/iterator_concepts.h:883:35:
>
> note: and 'std::ranges::basic_istream_view std::char_traits > &' does not satisfy '__member_begin'
>requires is_array_v<_Tp> || __member_begin<_Tp&> ||
> __adl_begin<_Tp&>
>^
> /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/bits/iterator_concepts.h:867:33:
>
> note: because '__detail::__decay_copy(__t.begin())' would be invalid: no
> member named 'begin' in 'std::ranges::basic_istream_view std::char_traits >'
>{ __detail::__decay_copy(__t.begin()) } ->
> input_or_output_iterator;
> ^
> /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/bits/iterator_concepts.h:883:59:
>
> note: and 'std::ranges::basic_istream_view std::char_traits > &' does not satisfy '__adl_begin'
>requires is_array_v<_Tp> || __member_begin<_Tp&> ||
> __adl_begin<_Tp&>
>^
> /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/bits/iterator_concepts.h:877:29:
>
> note: because '__detail::__decay_copy(begin(__t))' would be invalid:
> call to deleted function 'begin'
>{ __detail::__decay_copy(begin(__t)) } ->
> input_or_output_iterator;
> ^
> /usr/bin/..

Re: [cfe-users] _Decimal128 on PowerPC

2020-05-26 Thread Richard Smith via cfe-users
On Fri, 8 May 2020 at 00:09, Jeffrey Walton via cfe-users <
cfe-users@lists.llvm.org> wrote:

> Hi Everyone,
>
> I'm testing Steven Munroe's pveclib library
> (https://github.com/munroesj52/pveclib). It is testing OK with GCC,
> but I am having trouble with Clang.
>
> I've been able to test up to Clang 9 and with/without -std=c11, but I
> keep encountering two errors:
>
> decpowof2.c:30:7: error: GNU decimal type extension not supported
> const _Decimal128 decpowof2 [] = {
>
> decpowof2.c:31:8: error: invalid suffix 'DL' on floating constant
> 1.0E+0DL,   /* 2**0 */
>
> I believe _Decimal128 and the DL suffixes are part of ISO/IEC TS 18661
> or N2341 (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2341.pdf).
>

Clang does not implement ISO/IEC TS 18661-2 (decimal floating point).

It seems like a bug that our diagnostic claims this is a GNU extension,
since it's an ISO Technical Specification, but otherwise the diagnostic is
accurate. =(

We'd accept patches if you felt motivated to contribute an implementation,
but a high-quality implementation would likely be a fair amount of work
(LLVM has no support for decimal floating-point types yet).

I think I am missing the right combination of Clang compiler and options.
>
> What compiler or options are needed for Clang?
> ___
> cfe-users mailing list
> cfe-users@lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
>
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] Location of function name?

2020-05-26 Thread Richard Smith via cfe-users
On Fri, 22 May 2020 at 19:06, Sterling B via cfe-users <
cfe-users@lists.llvm.org> wrote:

> Hi Clang Experts, could you kindly advice how to get location of a
> function *name* when visiting FunctionDecl in RecursiveASTVisitor
> (getBeginLoc and getEndLoc return the whole range for the definition, not
> just the name). Example:
>
> For source code like this:
> int f(int x) { return x + 1; }
>
> this is the current code
>
> bool VisitFunctionDecl(clang::FunctionDecl *FD) {
> clang::ASTContext &context = FD->getASTContext();
> int begin = context.getFullLoc(FD->getBeginLoc()).getFileOffset();
> int end = context.getFullLoc(FD->getEndLoc()).getFileOffset();
> std::string path =
> context.getFullLoc(FD->getBeginLoc()).getFileEntry()->getName().str();
> .   ..
> }
>
> will give offsets [0,29], but I'd like to get the location of the "f",
> i.e. [5-6].
>

In general, you can use getLocation() to get the location of the name in a
NamedDecl. For a FunctionDecl, there's also getNameInfo(), which will
return more detailed information about the name of the function (allowing
you to handle the case where the function name is more than a single token,
such as for C++ functions with non-identifier names like "operator int*").
If you want to also include the preceding C++ nested name specifier as part
of the name, you can use getQualifierLoc to determine its location.


> Thanks!
> Sterling.
> ___
> cfe-users mailing list
> cfe-users@lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
>
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] Template parameter matcher?

2020-06-24 Thread Richard Smith via cfe-users
The declarations of tVal and tParam can be matched by
  varDecl(hasType(templateTypeParmType()))
The use of tVal can be matched by
  declRefExpr(hasDeclaration(varDecl(hasType(templateTypeParmType()

https://godbolt.org/z/B3SuC3


On Tue, 23 Jun 2020 at 15:47, Robert Ankeney via cfe-users <
cfe-users@lists.llvm.org> wrote:

> I'm looking for a matcher for variables whose type is a template
> parameter. For example:
>
> template
> T tVal;   // Match tVal
> int func(T tParam);   // Match tParam
> int i = func(tVal);   // Match tVal
>
> Our coding standards require the variable to have a 't' at the start of
> the variable name.
> Looking at the matcher reference, I didn't see anything obvious. Can
> anyone point me the right direction?
>
> Many thanks,
> Robert
>
> ___
> cfe-users mailing list
> cfe-users@lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
>
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] Template parameter matcher?

2020-06-29 Thread Richard Smith via cfe-users
On Fri, 26 Jun 2020 at 11:30, Robert Ankeney  wrote:

> Thanks Richard! This works great! One more question - assuming I have a
> templated class CClass, how would I match tVal for:
> void myFunc(CClass* tVal) ?
>

It depends exactly what you're looking for. If you don't care what CClass
is, and want to match any pointer to X<..., T, ...>, then something like:

varDecl(hasType(pointerType(pointee(templateSpecializationType(hasAnyTemplateArgument(refersToType(templateTypeParmType(

might be what you're looking for. If you want to match a T *anywhere* in
the variable's type, then maybe something like:

m
varDecl(hasType(qualType(hasDescendant(qualType(templateTypeParmType())

is what you want. https://godbolt.org/z/QhGN5d


> Oh, and thanks also for the godbolt link. I didn't realize you could do
> match testing there!
>
> Robert
>
>
> On Wed, Jun 24, 2020 at 10:38 AM Richard Smith 
> wrote:
>
>> The declarations of tVal and tParam can be matched by
>>   varDecl(hasType(templateTypeParmType()))
>> The use of tVal can be matched by
>>   declRefExpr(hasDeclaration(varDecl(hasType(templateTypeParmType()
>>
>> https://godbolt.org/z/B3SuC3
>>
>>
>> On Tue, 23 Jun 2020 at 15:47, Robert Ankeney via cfe-users <
>> cfe-users@lists.llvm.org> wrote:
>>
>>> I'm looking for a matcher for variables whose type is a template
>>> parameter. For example:
>>>
>>> template
>>> T tVal;   // Match tVal
>>> int func(T tParam);   // Match tParam
>>> int i = func(tVal);   // Match tVal
>>>
>>> Our coding standards require the variable to have a 't' at the start of
>>> the variable name.
>>> Looking at the matcher reference, I didn't see anything obvious. Can
>>> anyone point me the right direction?
>>>
>>> Many thanks,
>>> Robert
>>>
>>> ___
>>> cfe-users mailing list
>>> cfe-users@lists.llvm.org
>>> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
>>>
>>
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] inconsistent compilation error inside constexpr if

2020-08-23 Thread Richard Smith via cfe-users
On Fri, 21 Aug 2020 at 13:29, Manu agarwal via cfe-users <
cfe-users@lists.llvm.org> wrote:

> Hello,
>
> In the below code the compiler throws "undeclared identifier" when the
> commented line is uncommented. Whereas the line just before compiles fine.
>
> Regards,
> Manu
>
> typedef bool (* DummyFunc)   ();
>
>
> bool ExecDummy (DummyFunc fptr) {
>
> if (fptr)
> return fptr ();
>
> return false;
> }
>
> constexpr unsigned int IsMyAppClient = 0;
>
> constexpr bool CheckForTypeClient (unsigned int pAppType)
> {
> return ((pAppType & IsMyAppClient) != 0);
> }
>
>
> class  MyAppTemplate
> {
> public:
> template 
> staticboolMyAppInit ();
> };
>
> template 
> bool
> MyAppTemplate::MyAppInit ()
> {
> if constexpr (CheckForTypeClient(T)) {
>
> *return ClientMain ();// no error*
> *//return ExecDummy(ClientMain);// error: use of
> undeclared identifier 'ClientMain'*
> }
>

This code is invalid, as David Blaikie explains. However, in
MSVC-compatible mode (under -fms-compatibility, which is enabled by default
for some Windows-targeting modes), Clang attempts to to accept certain
invalid code that MSVC has historically accepted, including this case,
where we allow the call to ClientMain() to find declarations of a
ClientMain function that appear after the template definition. That
recovery from invalid code is only done for certain syntactic patterns,
such as unqualified function calls -- so it applies to ClientMain() but not
to (ClientMain).


> return false;
> }
>
> int __cdecl
> main (int pArgc, char* pArgv[])
> {
> constexpr int TVal = 3;
>
> MyAppTemplate::MyAppInit ();
>
> return 0;
> }
>
>
> ___
> cfe-users mailing list
> cfe-users@lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
>
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] Code which compiles with g++ but not with clang++

2020-11-09 Thread Richard Smith via cfe-users
On Thu, 5 Nov 2020 at 09:29, Marshall Clow via cfe-users <
cfe-users@lists.llvm.org> wrote:

> On Nov 5, 2020, at 6:34 AM, Pavel Černohorský via cfe-users <
> cfe-users@lists.llvm.org> wrote:
> >
> > Hello,
> >
> > I would like to ask what is wrong with the following code:
> > ```
> >
> > #include 
> >
> > struct S
> > {
> >S& operator=(S&) { return *this; };
> > };
> >
> > void thisWillNotCompileInClang()
> > {
> >   std::optional a;
> > }
> >
> > ```
> >
> > Compilation command is `g++ or clang++ -std=c++17 -c source.cpp`. It
> compiles without problems with g++ 9.3.0, but not with clang++ 10.0.0 (both
> from current stable Ubuntu 20). This code is simplification of code using
> widely adopted rapidjson library which uses assignment operator with
> non-const parameter a lot. Earlier versions of clang did not complain
> (tried with 7.0.1 on currently stable Debian Buster).
>
> A note from the libstdc++ maintainer:
>
> > I think there was a core change in C++20 to make the =default do the
> right thing (which is delete it, I think).
> > Clang does compile it with -std=c++20 just not -std=c++17.
>

Right, this was made valid by P0641R2, which was voted into C++20 but was
not moved as a defect report resolution against prior standards. So I think
g++ is being more permissive than the standard requires (though as far as I
can see, it would be a conforming extension to accept these cases
retroactively), and libstdc++ seems to be relying on that lenience
(probably unintentionally).


> — Marshall
>
>
> ___
> cfe-users mailing list
> cfe-users@lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
>
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] Missing AST Node for parsing code with std::vector::data()

2020-12-14 Thread Richard Smith via cfe-users
On Thu, 3 Dec 2020 at 04:02, Владимир Фролов via cfe-users <
cfe-users@lists.llvm.org> wrote:

> Greetings! I'm using clang for source-to-source translation.
>
> Recently I got a problem with parsing code which use templates.
> First, here is the working example:
>
> struct MyTestVector2
> {
>  unsigned int _data[6];
>  unsigned int * data() { return &_data[0]; }
> };
> ...
> MyTestVector2 testData2;
> kernel_TestColor(&hit,
> testData2.data(), tidX, tidY);
> This code processed normally and i gon correct "CXXMemberCallExpr" node
> for kernel_TestColor which i actually need.
> Then i changed MyTestVector2 to template:
>
> template
> struct MyTestVector2
> {
>  T _data[6];
>  T * data() { return &_data[0]; }
> };
>
> ...
> MyTestVector2 testData2;
> kernel_TestColor(&hit,
> testData2.data(), tidX, tidY);
>
> This time i got
>
> `-DeclStmt 0x5816e128 
>   `-VarDecl 0x5816e0c0  col:31 invalid testData2
> 'MyTestVector2':'MyTestVector2'
>
> This time, The AST node for kernel_TestColor is just missed!
> The code is absolutely correct itself, it can be build and run.
>

What interface are you using to parse the code with Clang? (libclang?
libTooling? Direct use of the C++ API?)

The above AST dump shows that Clang thinks the declaration of the variable
'testData2' is invalid (see the "invaild" in the declaration). Clang should
also have produced a diagnostic message explaining this, but some of the
ways of using Clang as a library don't set up a diagnostic consumer by
default, meaning that error message is just being thrown away. If you set
up a diagnostic consumer, Clang should tell you what's going wrong.

I suspect the problem is either something you elided in the above code or
it's an issue with the compilation flags in use, because the above example
in isolation looks fine.


> I'm using AST processing for code generation, so it is important for me to
> get  AST node for kernel_TestColor and then analyze its arguments.
> I understand that this seems to be not a bug, but ... may be, there is a
> way to make parser more tolerant to data types ... because what i actually
> need is just a strings of all parameters, so, just having "
> testData2.data()" at some level of AST for the second parameter of 
> kernel_TestColor
> would be enough for me.
>
> I would be appretiate for help or advice.
> Currently i use llvm 10.
> Thanks!
> --
> Best Regards,
>  Frolov V.A.
>
> ___
> cfe-users mailing list
> cfe-users@lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
>
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] How to find the physical end of an expression?

2021-05-05 Thread Richard Smith via cfe-users
On Wed, 28 Apr 2021 at 13:53, Taylor, Max via cfe-users <
cfe-users@lists.llvm.org> wrote:

> Greetings.
>
>
>
> I’m building a source-to-source tool with clang. What I want to do is
> instrument stores made with the binary = operator. Currently, I’m running
> into problems with rewriting expressions that contain macro invocations.
> I’ve done some digging around, and I found some info  that helped with my
> understanding (e.g.
> https://stackoverflow.com/questions/24062989/clang-fails-replacing-a-statement-if-it-contains-a-macro).
> But I’m still not sure how to solve this problem.
>
>
>
> Concretely, suppose you have:
>
> #define a(x) ((x) * 10 + 1)
>
>
>
> class my_class {
>
> int x;
>
>
>
> public:
>
> int my_function() {
>
> x = a(0);
>
> return x;
>
> }
>
> };
>
>
>
> I want to rewrite this into something like this:
>
> #ifndef _instrument_noclash
>
> #define _instrument_noclash(name, expr, instance_no)
>  \
>
> (*({
>\
>
> typeof(expr) *_t_instrument_no_clash##instance_no = &(expr);
>   \
>
> _t_instrument_no_clash##instance_no;
>   \
>
> }))
>
> #endif
>
>
>
> #define a(x) ((x) * 10 + 1)
>
>
>
> class my_class {
>
> int x;
>
> public:
>
> int my_function() {
>
> _instrument_noclash("x",(this->x=((0) * 10 + 1)),0);
>
> return x;
>
> }
>
> };
>
>
>
> The problem (to me) is simple: *how do I determine the physical location
> of the ending of the expression on the right hand sign of the = operator? 
> *Without
> this knowledge, I end up overwriting the end of the statement. Scanning the
> APIs, it seems like there isn’t a simple way to do this. I’ve tried several
> ways to get the ending source location:
>
>1. op->getEndLoc(), where op is an instance of BinaryOperator. This
>doesn’t work, because the ending location in the AST is not the same as the
>physical end location of the expression, due to macro expansion.
>2. sm.getSpellingLoc(op->getEndLoc()), where sm is the source manager.
>This just returns op->getEndLoc().
>3. sm.getExpansionLoc(op->getEndLoc()). This is close, but the
>location returned is the end of the macro name, so the macro arguments are
>not removed.
>
> sm.getExpansionRange(op->getEndLoc()).getEnd() should work in this case.
In general what you're trying to do is not possible, because the assignment
expression might end in the middle of the macro expansion, though;
depending on exactly what your goal is, it might be easiest to first
preprocess the source file and then run your transform.


> Any suggestions (or easier way to achieve this same goal) are appreciated.
>
>
>
> -Max
> ___
> cfe-users mailing list
> cfe-users@lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
>
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] Removing or obfuscating RTTI type name strings

2021-09-03 Thread Richard Smith via cfe-users
On Fri, 27 Aug 2021 at 11:03, Andy Gibbs via cfe-users <
cfe-users@lists.llvm.org> wrote:

> Hi there,
>
> I'm hitting a rather difficult problem.  I have to compile with RTTI data
> structures generated because, even though I am not using dynamic_cast or
> typeid in my application code, I am linking and using a library that does
> use dynamic_cast.  Therefore my code will crash if I compile with -fno-rtti.
>
> The problem is, then, that the size of my code is greatly increased, and
> also (which is more important) critical information is being leached into
> the resulting application binary by the RTTI type name string that is
> generated.  Unlike normal symbols, these cannot be stripped from the
> executable.
>
> Therefore I would like to make a change to the clang compiler to either
> replace all the type name strings with a single "?" string (this would be
> best) or doing something like a rot-x encryption on the complete string (I
> would rather not do this since these strings are literally hundreds of
> characters long given that the types are complex template types).
>
> My suggestion would be that I would attempt to add a -fno-rtti-names
> parameter.  If this is of interest to the general clang community I would
> be happy to submit a patch for consideration, but at the very least I need
> something for my own purposes.
>
> This brings me to my request.  I would be very grateful if someone here
> might be able to direct me into the right place for making such a change.
>
> Looking at the source code there is a
> ItaniumRTTIBuilder::BuildTypeInfo(...) function in
> CodeGen/ItaniumCXXABI.cpp (see
> https://github.com/llvm/llvm-project/blob/fe177a1773e4f88dde1aa37d34a0d3f8cb582f14/clang/lib/CodeGen/ItaniumCXXABI.cpp#L3730).
> In there, the first thing it does is lay down a field for the mangled type
> name.  My guess is that it should be possible to substitute the line
>
> llvm::GlobalVariable *TypeName = GetAddrOfTypeName(Ty, Linkage);
>
> with something that generates a static string "?" and returns the address
> of that.  Then it will build the table pointing at this string, I am
> guessing.
>
> Is this a feasible approach or will this break loads of things elsewhere
> in the compiler and/or c++ runtime?  I am not interested in a run-time
> ability to get the mangled (or otherwise) name of the class, so if
> replacing this string has no effect on, for example, the correction
> function of dynamic_cast or typeid and only means that std::type_info::name
> returns a bogus value, then I'm happy with that.
>

The address and (sometimes) contents of the _ZTS type_info name are used
for type_info equality comparisons. The implementation of dynamic_cast
internally uses type_info comparisons to find the destination type within
the source type's type_info tree. So changing the contents of the string to
be non-unique may lead to problems, especially if the ABI rule in question
results in the use of strcmp. You could perhaps instead consider replacing
the string contents with something like a hash of the mangled name of the
type (though be aware that the ABI library will want to interpret it as a
nul-terminated byte string).
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users