Commit ce41c99b authored by Milian Wolff's avatar Milian Wolff
Browse files

Fake malloc attribute to improve compatibility with GCC 11 and higher

On my system I regularly see bogus compiler warnings reported by clang
within KDevelop, such as:

```
/usr/include/stdlib.h:566:5: error: use of undeclared identifier '__builtin_free'; did you mean '__builtin_frexp'?
/usr/include/stdlib.h:566:5: note: '__builtin_frexp' declared here
/usr/include/stdlib.h:566:5: error: '__malloc__' attribute takes no arguments
/usr/include/stdlib.h:570:14: error: '__malloc__' attribute takes no arguments
/usr/include/stdlib.h:799:6: error: use of undeclared identifier '__builtin_free'; did you mean '__builtin_frexp'?
/usr/include/stdlib.h:566:5: note: '__builtin_frexp' declared here
/usr/include/stdlib.h:799:6: error: '__malloc__' attribute takes no arguments
```

The reason is that e.g. `/usr/include/sys/cdefs.h` contains:

```
#if __GNUC_PREREQ (11, 0)
/* Designates dealloc as a function to call to deallocate objects
   allocated by the declared function.  */
# define __attr_dealloc(dealloc, argno) \
    __attribute__ ((__malloc__ (dealloc, argno)))
# define __attr_dealloc_free __attr_dealloc (__builtin_free, 1)
#else
# define __attr_dealloc(dealloc, argno)
# define __attr_dealloc_free
#endif
```

In KDevelop, we ask cmake to tell us the compiler (in my case GCC)
and then query it for its defines. Then we parse the code with
libclang which then tries to parse the above (as it thinks we are GCC)
but fails because clang does not yet support a malloc attribute with
positional arguments, contrary to GCC.

By injecting a fake `__malloc__` define we can silence this error,
seemingly without side effects. As `__*__` is a reserved identifier
I don't think we can break user code with this and should be
relatively safe.
parent e598d702
......@@ -275,7 +275,7 @@ ParseSessionData::ParseSessionData(const QVector<UnsavedFile>& unsavedFiles, Cla
smartArgs << ClangHelpers::clangBuiltinIncludePath().toUtf8();
clangArguments << "-isystem" << smartArgs.last().constData();
if (!environment.defines().isEmpty()) {
{
smartArgs << writeDefinesFile(environment.defines());
clangArguments << "-imacros" << smartArgs.last().constData();
}
......@@ -357,6 +357,19 @@ QByteArray ParseSessionData::writeDefinesFile(const QMap<QString, QString>& defi
}
definesStream << QLatin1String("#define ") << it.key() << ' ' << it.value() << '\n';
}
if (!defines.contains(QStringLiteral("__clang__")) && defines.value(QStringLiteral("__GNUC__")).toInt() >= 11) {
/* fake GCC compatibility for __malloc__ attribute with arguments to silence warnings like this:
/usr/include/stdlib.h:566:5: error: use of undeclared identifier '__builtin_free'; did you mean
'__builtin_frexp'? /usr/include/stdlib.h:566:5: note: '__builtin_frexp' declared here
/usr/include/stdlib.h:566:5: error: '__malloc__' attribute takes no arguments
/usr/include/stdlib.h:570:14: error: '__malloc__' attribute takes no arguments
/usr/include/stdlib.h:799:6: error: use of undeclared identifier '__builtin_free'; did you mean
'__builtin_frexp'? /usr/include/stdlib.h:566:5: note: '__builtin_frexp' declared here
/usr/include/stdlib.h:799:6: error: '__malloc__' attribute takes no arguments
*/
definesStream << QLatin1String("#define __malloc__(...) __malloc__\n");
}
}
m_definesFile.close();
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment