[Bug c++/79508] New: Parse error in template argument list using nested template arguments

2017-02-14 Thread trufanovan at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79508

Bug ID: 79508
   Summary: Parse error in template argument list using nested
template arguments
   Product: gcc
   Version: 6.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: trufanovan at gmail dot com
  Target Milestone: ---

Created attachment 40738
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40738&action=edit
ii file

It's probably a regression.
I was trying to compile a popular opensourse project on my Kubuntu 16.10
4.8.0-38-generic with gcc 6.2.0 20161005 and got a compilation error.
The original problem was reported to project authors on GitHub:
https://github.com/JohnLangford/vowpal_wabbit/issues/1183
We found out that it's gcc version specific - it works for clang and gcc
4.6-4.9.

I've simplified the code. The sample to reproduce the problem is:

> code start: t.cpp
class C
{
public: 
template< void(*F)()> void set_default() {  }   
};


template  void random_positive()
{
}

template void initialize(T& x)
{
x.template set_default >();
}

int main ()
{
C x;
initialize(x);
}
>code end: t.cpp

I'm getting 

> compilation output:
t.cpp: In function ‘void initialize(T&)’:
t.cpp:18:12: error: parse error in template argument list
 x.template set_default >();
^~
t.cpp:18:12: error: expected identifier

> compilation output end

Below are commad lines for old g++ and clangs that doesn't cause the problem so
produce no output to console + the command line of g++-6 with all verbose :


>truf@truf-laptop:~$ clear
>truf@truf-laptop:~$ /usr/bin/g++-4.6  -Wall -Wextra -c t.cpp -o t.o
>truf@truf-laptop:~$ /usr/bin/g++-4.8  -Wall -Wextra -c t.cpp -o t.o
>truf@truf-laptop:~$ /usr/bin/g++-4.9  -Wall -Wextra -c t.cpp -o t.o
>truf@truf-laptop:~$ /usr/bin/clang++-3.6  -Wall -Wextra -c t.cpp -o t.o
>truf@truf-laptop:~$ /usr/bin/clang++-3.8  -Wall -Wextra -c t.cpp -o t.o
>truf@truf-laptop:~$ /usr/bin/g++-6  -Wall -Wextra -c t.cpp -o t.o
t.cpp: In function ‘void initialize(T&)’:
t.cpp:18:12: error: parse error in template argument list
 x.template set_default >();
^~
t.cpp:18:12: error: expected identifier
>truf@truf-laptop:~$ /usr/bin/g++-6  -v -save-temps -Wall -Wextra 
>-fno-strict-aliasing -fwrapv -fno-aggressive-loop-optimizations -c t.cpp -o t.o
Using built-in specs.
COLLECT_GCC=/usr/bin/g++-6
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 6.2.0-5ubuntu12'
--with-bugurl=file:///usr/share/doc/gcc-6/README.Bugs
--enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr
--program-suffix=-6 --program-prefix=x86_64-linux-gnu- --enable-shared
--enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext
--enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/
--enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes
--with-default-libstdcxx-abi=new --enable-gnu-unique-object
--disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie
--with-system-zlib --disable-browser-plugin --enable-java-awt=gtk
--enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-6-amd64/jre
--enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-6-amd64
--with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-6-amd64
--with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar
--enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686
--with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib
--with-tune=generic --enable-checking=release --build=x86_64-linux-gnu
--host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 6.2.0 20161005 (Ubuntu 6.2.0-5ubuntu12) 
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-Wall' '-Wextra' '-fno-strict-aliasing'
'-fwrapv' '-fno-aggressive-loop-optimizations' '-c' '-o' 't.o' '-shared-libgcc'
'-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-linux-gnu/6/cc1plus -E -quiet -v -imultiarch
x86_64-linux-gnu -D_GNU_SOURCE t.cpp -mtune=generic -march=x86-64 -Wall -Wextra
-fno-strict-aliasing -fwrapv -fno-aggressive-loop-optimizations
-fpch-preprocess -fstack-protector-strong -Wformat-security -o t.ii
ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/6"
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory
"/usr/lib/gcc/x86_64-linux-gnu/6/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/includ

[Bug c++/79508] [6/7 Regression] Parse error in template argument list using nested template arguments

2017-02-14 Thread trufanovan at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79508

--- Comment #3 from Alexander Trufanov  ---
>When looking for a template after . or ->, only consider class templates.

Looks like it means the problem at least can be workarounded by wrapping
function into a class. The code:

>code
class C
{
public: 
template< class T> void set_default() { }   
};

template  class random_positive_wrapper
{
 void random_positive() { }
};

template void initialize(T& x)
{
x.template set_default >();
}

int main ()
{
C x;
initialize(x);
}

>code end

works:

truf@truf-laptop:~$ /usr/bin/g++  -Wall -Wextra -c t.cpp -o t.o
truf@truf-laptop:~$ /usr/bin/g++-4.6  -Wall -Wextra -c t.cpp -o t.o
truf@truf-laptop:~$ /usr/bin/g++-4.8  -Wall -Wextra -c t.cpp -o t.o
truf@truf-laptop:~$ /usr/bin/g++-4.9  -Wall -Wextra -c t.cpp -o t.o
truf@truf-laptop:~$ /usr/bin/clang++-3.6  -Wall -Wextra -c t.cpp -o t.o
truf@truf-laptop:~$ /usr/bin/clang++-3.8  -Wall -Wextra -c t.cpp -o t.o
truf@truf-laptop:~$ /usr/bin/g++-6  -Wall -Wextra -c t.cpp -o t.o
truf@truf-laptop:~$

[Bug c++/66316] New: Usage of wrong template function for classes in different modules but having the same name

2015-05-27 Thread trufanovan at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66316

Bug ID: 66316
   Summary: Usage of wrong template function for classes in
different modules but having the same name
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: minor
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: trufanovan at gmail dot com
  Target Milestone: ---

gcc version 4.9.2 (Ubuntu 4.9.2-10ubuntu13) 
Full gcc -v output is here: http://pastebin.com/apZhYVUU

gcc is used via latest QtCreator. The problem is reproducible in debug build
mode only. Unfortunately, I don't know which gcc parameters Qt toolchain is
using with debug builds.

Additional parameters specified in my project file: -std=c++11 (may be
irrelevant - didn't check)

Original problem description:
https://github.com/JohnLangford/vowpal_wabbit/issues/655

Description:

Application has two .cpp modules. Let's say 1.cpp and 2.cpp.
In each module there is a definition of struct N. Name N is the same for both.
So we have two different structure declarations with the same name N. Compiler
gives ok for such naming as they are not exposed from their modules and used
internally in them. No namespaces are used.

And structures have different number of fields. One has 1 field and another is
6 fields long.

There is also a template function in a header file 3.h which is used in both (
1.cpp and 2.cpp) for objects allocation. It's:

template 
T* calloc_or_die()
{
  void* data = calloc(1, sizeof(T));
  if (data == nullptr) throw std::exception();
  return (T*)data;
}

Its usage:
 N& data& = *calloc_or_die(); // same usage for both modules

Both cpp files call this function each for its own structure N.

The problem is in following:

In debug builds compiler might use calloc_or_die implementation of one
struct to allocate memory for another. As they have different number of fields
the sizeof(T) will be different. So you might allocate 8 bites (1 field struct)
but access it via pointer to struct with size 48 bites (6 field struct). In
this case if you once write something to fields #2-#6 the app will eventually
randomly crashes with SEGFAULT at some free() function call. free() may be
called even not for these classes. It just some memory corruption flag that
raised after accessing unallocated memory block or something like that.

Valgrind used with -fmudflap flag is able to detect line where memory
corruption happens. Thus I was able to debug this.

I believe that compiler mistakenly links to a wrong implementation of
calloc_or_die. The problem was workarounded by simple renaming struct N
declaration in one of modules to M.