gcc/libgomp/error.c
Jakub Jelinek 0d973c0a0d openmp: Implement the error directive
This patch implements the error directive.  Depending on clauses it is either
a compile time diagnostics (in that case diagnosed right away) or runtime
diagnostics (libgomp API call that diagnoses at runtime), and either fatal
or warning (error or warning at compile time or fatal error vs. error at
runtime) and either has no message or user supplied message (this kind of
e.g. deprecated attribute).  The directive is also stand-alone directive
when at runtime while utility (thus disappears from the IL as if it wasn't
there for parsing like nothing directive) at compile time.

There are some clarifications in the works ATM, so this patch doesn't yet
require that for compile time diagnostics the user message must be a constant
string literal, there are uncertainities on what exactly is valid argument
of message clause (whether just const char * type, convertible to const char *,
qualified/unqualified const char * or char * or what else) and what to do
in templates.  Currently even in templates it is diagnosed right away for
compile time diagnostics, if we'll need to substitute it, we'd need to queue
something into the IL, have pt.c handle it and diagnose only later.

2021-08-20  Jakub Jelinek  <jakub@redhat.com>

gcc/
	* omp-builtins.def (BUILT_IN_GOMP_WARNING, BUILT_IN_GOMP_ERROR): New
	builtins.
gcc/c-family/
	* c-pragma.h (enum pragma_kind): Add PRAGMA_OMP_ERROR.
	* c-pragma.c (omp_pragmas): Add error directive.
	* c-omp.c (omp_directives): Uncomment error directive entry.
gcc/c/
	* c-parser.c (c_parser_omp_error): New function.
	(c_parser_pragma): Handle PRAGMA_OMP_ERROR.
gcc/cp/
	* parser.c (cp_parser_handle_statement_omp_attributes): Determine if
	PRAGMA_OMP_ERROR directive is C_OMP_DIR_STANDALONE.
	(cp_parser_omp_error): New function.
	(cp_parser_pragma): Handle PRAGMA_OMP_ERROR.
gcc/fortran/
	* types.def (BT_FN_VOID_CONST_PTR_SIZE): New DEF_FUNCTION_TYPE_2.
	* f95-lang.c (ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST): Define.
gcc/testsuite/
	* c-c++-common/gomp/error-1.c: New test.
	* c-c++-common/gomp/error-2.c: New test.
	* c-c++-common/gomp/error-3.c: New test.
	* g++.dg/gomp/attrs-1.C (bar): Add error directive test.
	* g++.dg/gomp/attrs-2.C (bar): Add error directive test.
	* g++.dg/gomp/attrs-13.C: New test.
	* g++.dg/gomp/error-1.C: New test.
libgomp/
	* libgomp.map (GOMP_5.1): Add GOMP_error and GOMP_warning.
	* libgomp_g.h (GOMP_warning, GOMP_error): Declare.
	* error.c (GOMP_warning, GOMP_error): New functions.
	* testsuite/libgomp.c-c++-common/error-1.c: New test.
2021-08-20 11:36:52 +02:00

123 lines
3.1 KiB
C

/* Copyright (C) 2005-2021 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
(libgomp).
Libgomp is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
/* This file contains routines used to signal errors. Most places in the
OpenMP API do not make any provision for failure, so we can't just
defer the decision on reporting the problem to the user; we must do it
ourselves or not at all. */
/* ??? Is this about what other implementations do? Assume stderr hasn't
been pointed somewhere unsafe? */
#include "libgomp.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#undef gomp_vdebug
void
gomp_vdebug (int kind __attribute__ ((unused)), const char *msg, va_list list)
{
if (gomp_debug_var)
vfprintf (stderr, msg, list);
}
#undef gomp_debug
void
gomp_debug (int kind, const char *msg, ...)
{
va_list list;
va_start (list, msg);
gomp_vdebug (kind, msg, list);
va_end (list);
}
void
gomp_verror (const char *fmt, va_list list)
{
fputs ("\nlibgomp: ", stderr);
vfprintf (stderr, fmt, list);
fputc ('\n', stderr);
}
void
gomp_error (const char *fmt, ...)
{
va_list list;
va_start (list, fmt);
gomp_verror (fmt, list);
va_end (list);
}
void
gomp_vfatal (const char *fmt, va_list list)
{
gomp_verror (fmt, list);
exit (EXIT_FAILURE);
}
void
gomp_fatal (const char *fmt, ...)
{
va_list list;
va_start (list, fmt);
gomp_vfatal (fmt, list);
va_end (list);
}
void
GOMP_warning (const char *msg, size_t msglen)
{
if (msg && msglen == (size_t) -1)
gomp_error ("error directive encountered: %s", msg);
else if (msg)
{
fputs ("\nlibgomp: error directive encountered: ", stderr);
fwrite (msg, 1, msglen, stderr);
fputc ('\n', stderr);
}
else
gomp_error ("error directive encountered");
}
void
GOMP_error (const char *msg, size_t msglen)
{
if (msg && msglen == (size_t) -1)
gomp_fatal ("fatal error: error directive encountered: %s", msg);
else if (msg)
{
fputs ("\nlibgomp: fatal error: error directive encountered: ", stderr);
fwrite (msg, 1, msglen, stderr);
fputc ('\n', stderr);
exit (EXIT_FAILURE);
}
else
gomp_fatal ("fatal error: error directive encountered");
}