Clang compiler option to treat exception specification lax error as warning - c++

Is there a way to treat exception mismatch error as warning in clang?
source_file.cpp:12:18: error: exception specification of overriding function is more lax than base version
virtual void Func(){}
I am getting error with google mock for functions that specify exception specifier. Looking at https://github.com/google/googletest/pull/681 and other reported issue, not sure if this will get fixed in google mock, so at least for test code if possible I would like to disable this.
//clang 3.8.0
#include <iostream>
struct A
{
virtual void Func() throw() {}
};
struct B : public A
{
virtual void Func(){}
};
int main()
{
B b;
return 0;
}

Yes, using the -fms-extensions command line option.
MSVC only warns about this, so with clang MSVC compatibility mode, the code will compile, and the error will be replaced with an equivalent warning.
More about MSVC compatibility mode in clang documentation,
here.

Related

Expected ambiguity error on clang is not present

This needs little explanation, but I'm expecting to get an ambiguity error from the following C++ code, however my compiler gives me different results that are apparently not part of the standard.
Environment:
Windows
Clang++ version 12.0.0
Clang++ target = x86_64-pc-windows-msvc
#include <iostream>
void print(int x) {
std::cout << "INT\n";
}
void print(double d) {
std::cout << "DOUBLE\n";
}
int main() {
print(5l); // 5l is type long, should cause ambiguity
}
output:
INT
Any idea why this is happening? My compiler is choosing the function taking an int for some reason instead of issuing an ambiguity error since it shouldn't be able to resolve the function call. Is there some conversion logic that I missed? Do I need to turn up some 'error levels' or something along those lines? Or is this a bug in the compiler? Thanks.
Turned out I had to add -fno-ms-compatibility to my clang compiler flags to switch off MSVC compatibility.

gcc warning about unitialized values caused by turning optimization on

Consider the following code
#include <iostream>
template<typename Value>
struct Wrapper {
Value m_value;
Wrapper() {}
Wrapper(const Wrapper<Value> &copy_from) : m_value(copy_from.m_value) {}
};
template<typename Value>
struct DefaultContainer {
Value m_default;
DefaultContainer(const Value& def) : m_default(def) {}
};
template<typename Value>
struct DefaultContainerUser : public DefaultContainer<Value> {
DefaultContainerUser() : DefaultContainer<Value>(Value()) {}
};
int main() {
DefaultContainerUser<Wrapper<double>> user;
std::cout << user.m_default.m_value << std::endl;
}
When I compile this with c++ -O1 -Werror -Wall test.cpp, I get the following error:
test.cpp: In function ‘int main()’:
test.cpp:8:63: error: ‘<anonymous>.Wrapper<double>::m_value’ is used uninitialized in this function [-Werror=uninitialized]
8 | Wrapper(const Wrapper<Value> &copy_from) : m_value(copy_from.m_value) {}
| ~~~~~~~~~~^~~~~~~
cc1plus: all warnings being treated as errors
If I disable optimizations using -O0, everything works fine. Adding -Wno-error=maybe-uninitialized with optimizations still turned on doesn't help. What am I doing wrong here?
The compiler that I'm using is c++ (GCC) 10.2.1 20201016 (Red Hat 10.2.1-6).
It is normal that the warnings reported by a compiler varies depending on the optimization level. Warnings are usually a bi-product of optimization in the sense that the analysis needed for a particular optimization may uncover possible problems in the code or that transformations applied during optimization may uncover possible errors. This implies that when optimization is off and the analysis and transformations are not performed the problems are not detected.

Syntax for attributes for constructors

What is the proper location for an attribute specifier for a constructor? The standard doesn't seem to distinguish constructor in any special way but the normal locations lead to warnings from GCC and Clang.
struct test {
[[gnu::nonnull]] test (char * arg); // gcc-6.3 ok, clang error.
test [[gnu::nonnull]] (signed * arg); // gcc/clang error
test (unsigned * arg) [[gnu::nonnull]]; // gcc warning, clang error.
};
I use the second for other functions with no issues.
Is this a bug in gcc and clang?

Clang warning in dubious case: function 'foo' could be declared with attribute 'noreturn'?

I have been playing around a bit with the [[noreturn]] attribute, which I'm trying to get a handle of and make use of (I understand [[noreturn]] is a C++11 standard attribute and __attribute__((noreturn)) is a GCC/Clang extension). As part of this, I enabled the Clang warning -Wmissing-noreturn.
> clang++ -v
Ubuntu clang version 3.7.1-svn253742-1~exp1 (branches/release_37) (based on LLVM 3.7.1)
Target: x86_64-pc-linux-gnu
Thread model: posix
foo.cpp:
enum bar
{
A = 1,
B,
C
};
void foo()
{
switch (bar())
{
case A:
case B:
case C:
default:
break;
}
}
int main()
{
foo();
return 0;
}
Then compile:
> clang++ foo.cpp -o foo -Wmissing-noreturn -std=c++14
foo.cpp:9:1: warning: function 'foo' could be declared with attribute 'noreturn'
[-Wmissing-noreturn]
{
^
1 warning generated.
It appears to me that it would return! What's going on here? Is this a compiler bug?
If you remove the "= 1" from A, then it compiles fine without a warning.
If I do make the foo() function [[noreturn]] void foo(), then it does crash with a segmentation fault.
Ok sorry for delete the last answer. It was wrong. Ok noreturn meann that the function never end. and the segementation fould is because bar is not a variable
Just to give a follow up to an old question: clang is correct, even if a little pedantic.
Indeed the attribute noreturn is applicable to your foo() function, since it doesn't return anything. The fact that clang of 2016 gets confused with the slight variation in the enumeration that is a problem.
But we should forgive clang for this pecadillo, for C++11 grammar is not what could be called very simple.

using g++, how to deprecate virtual class member functions

I seem to be having trouble getting deprecated warnings to print out, for functions declared as virtual.
I'm using "g++ (GCC) 4.1.1 20061011 (Red Hat 4.1.1-30)."
My research shows that there might be problems in gcc 4.x regarding deprecating
pure virtual functions(i.e. class bueller{ virtual int cameron()=0;};),
but not... I'd guess you'd call them regular... virtual functions.
Just so we're on the same page...
foo.h
class Foo
{
void Foo_A() __attribute__((deprecated)); //non-virtual
virtual void Foo_B() __attribute__((deprecated)); //virtual
virtual void Foo_C() __attribute__((deprecated)) = 0; //pure virtual
};
Say I compiled this, an foo.cpp file and some main.cpp file using g++.
1)Anything that uses Foo_A() will indeed show a warning.
2)Anything that uses Foo_B() does NOT show a warning.
3)Anything that inherits Foo, implements Foo_C and then uses it does not show warning.
Number 1: it works, no problem.
Number 3: seems like a known bug/feature.. whatever..
There seems to be no explination for #2 however.
Perhaps it's tied up in #3, although nothing I've found makes mention of it.
Anyone know if I'm missing anything here regarding regular virtual class member functions that I want to deprecate?
BTW: -Wno-deprecate is NOT turned on in my makefiles.
Given this program:
struct Foo
{
virtual void Foo_B() __attribute__((deprecated)); //virtual
};
struct DerivedFoo : public Foo
{
};
int main()
{
DerivedFoo d;
d.Foo_B();
Foo &f = d;
f.Foo_B();
}
void Foo::Foo_B() {}
On CentOS 5.2 (gcc version 4.1.2 20080704 (Red Hat 4.1.2-44)), I get the same output that you describe:
g++ deprecate.cc -o deprecate
deprecate.cc: In function ‘int main()’:
deprecate.cc:14: warning: ‘Foo_B’ is deprecated (declared at deprecate.cc:3)
But, on Ubuntu 10.04.1 (gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)), I get the output that you expect:
g++ deprecate.cc -o deprecate
deprecate.cc: In function ‘int main()’:
deprecate.cc:14: warning: ‘virtual void Foo::Foo_B()’ is deprecated (declared at deprecate.cc:3)
deprecate.cc:16: warning: ‘virtual void Foo::Foo_B()’ is deprecated (declared at deprecate.cc:3)
So, I'm guessing it was a compiler bug that got fixed.
Do you call Foo_B()/Foo_C() through a Foo pointer/reference, or a derived class? If you use a derived class it seems that you have to mark the methods deprecated in it as well, or you get the behaviour you describe.
Google shows an old discussion on this topic at a Debian list. But nothing more recent comes up on this topic. Try asking on the distribution's (RedHat's, in this case) lists.